[ALSA] Optimize for config without PROC_FS
authorTakashi Iwai <tiwai@suse.de>
Thu, 1 Dec 2005 09:42:42 +0000 (10:42 +0100)
committerJaroslav Kysela <perex@suse.cz>
Tue, 3 Jan 2006 11:30:02 +0000 (12:30 +0100)
Modules: HWDEP Midlevel,ALSA Core,PCM Midlevel,Timer Midlevel

Optimize the code when compiled without CONFIG_PROC_FS.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/info.h
sound/core/hwdep.c
sound/core/info.c
sound/core/init.c
sound/core/pcm.c
sound/core/pcm_memory.c
sound/core/sound.c
sound/core/sound_oss.c
sound/core/timer.c

index df03e6017547f12b2b7b2c539a8da02de1e6b55b..8ea5c7497c03df2e83865d49fb87b783035ed921 100644 (file)
@@ -87,8 +87,6 @@ struct snd_info_entry {
        struct semaphore access;
 };
 
-int snd_info_check_reserved_words(const char *str);
-
 #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
 int snd_info_minor_register(void);
 int snd_info_minor_unregister(void);
@@ -142,6 +140,7 @@ static inline void snd_info_set_text_ops(struct snd_info_entry *entry,
        entry->c.text.read = read;
 }
 
+int snd_info_check_reserved_words(const char *str);
 
 #else
 
@@ -164,8 +163,14 @@ static inline int snd_info_card_free(struct snd_card * card) { return 0; }
 static inline int snd_info_register(struct snd_info_entry * entry) { return 0; }
 static inline int snd_info_unregister(struct snd_info_entry * entry) { return 0; }
 
-#define snd_card_proc_new(card,name,entryp)  0 /* always success */
-#define snd_info_set_text_ops(entry,private_data,read_size,read) /*NOP*/
+static inline int snd_card_proc_new(struct snd_card *card, const char *name,
+                                   struct snd_info_entry **entryp) { return -EINVAL; }
+static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)),
+                                        void *private_data,
+                                        long read_size,
+                                        void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {}
+
+static inline int snd_info_check_reserved_words(const char *str) { return 1; }
 
 #endif
 
index b8c0c8c4d126416c2fee2ce4e997bdfaeca9b3ab..618c43be0bc36e35cd9915fe9652c36ebd3f3fc6 100644 (file)
@@ -458,6 +458,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
        return snd_hwdep_free(hwdep);
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
@@ -477,13 +478,9 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
        up(&register_mutex);
 }
 
-/*
- *  ENTRY functions
- */
+static struct snd_info_entry *snd_hwdep_proc_entry;
 
-static struct snd_info_entry *snd_hwdep_proc_entry = NULL;
-
-static int __init alsa_hwdep_init(void)
+static void __init snd_hwdep_proc_init(void)
 {
        struct snd_info_entry *entry;
 
@@ -496,6 +493,25 @@ static int __init alsa_hwdep_init(void)
                }
        }
        snd_hwdep_proc_entry = entry;
+}
+
+static void __exit snd_hwdep_proc_done(void)
+{
+       snd_info_unregister(snd_hwdep_proc_entry);
+}
+#else /* !CONFIG_PROC_FS */
+#define snd_hwdep_proc_init()
+#define snd_hwdep_proc_done()
+#endif /* CONFIG_PROC_FS */
+
+
+/*
+ *  ENTRY functions
+ */
+
+static int __init alsa_hwdep_init(void)
+{
+       snd_hwdep_proc_init();
        snd_ctl_register_ioctl(snd_hwdep_control_ioctl);
        snd_ctl_register_ioctl_compat(snd_hwdep_control_ioctl);
        return 0;
@@ -505,10 +521,7 @@ static void __exit alsa_hwdep_exit(void)
 {
        snd_ctl_unregister_ioctl(snd_hwdep_control_ioctl);
        snd_ctl_unregister_ioctl_compat(snd_hwdep_control_ioctl);
-       if (snd_hwdep_proc_entry) {
-               snd_info_unregister(snd_hwdep_proc_entry);
-               snd_hwdep_proc_entry = NULL;
-       }
+       snd_hwdep_proc_done();
 }
 
 module_init(alsa_hwdep_init)
index ec3282f266f001c749a48fed2e8c6009ffff8f79..ae88539214644d365506176561f3f4928adcd282 100644 (file)
@@ -37,6 +37,8 @@
  *
  */
 
+#ifdef CONFIG_PROC_FS
+
 int snd_info_check_reserved_words(const char *str)
 {
        static char *reserved[] =
@@ -66,8 +68,6 @@ int snd_info_check_reserved_words(const char *str)
        return 1;
 }
 
-#ifdef CONFIG_PROC_FS
-
 static DECLARE_MUTEX(info_mutex);
 
 struct snd_info_private_data {
@@ -580,12 +580,10 @@ int __exit snd_info_done(void)
        snd_info_version_done();
        if (snd_proc_root) {
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-               if (snd_seq_root)
-                       snd_info_unregister(snd_seq_root);
+               snd_info_unregister(snd_seq_root);
 #endif
 #ifdef CONFIG_SND_OSSEMUL
-               if (snd_oss_root)
-                       snd_info_unregister(snd_oss_root);
+               snd_info_unregister(snd_oss_root);
 #endif
                snd_remove_proc_entry(&proc_root, snd_proc_root);
        }
@@ -937,7 +935,8 @@ int snd_info_unregister(struct snd_info_entry * entry)
 {
        struct proc_dir_entry *root;
 
-       snd_assert(entry != NULL, return -ENXIO);
+       if (! entry)
+               return 0;
        snd_assert(entry->p != NULL, return -ENXIO);
        root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
        snd_assert(root, return -ENXIO);
index 58e17d385f8d9cc65a58cdfa84a13a64f6d63b0d..75816688607c7ea7da5e52294f0c7e2491feb21a 100644 (file)
@@ -46,12 +46,39 @@ DEFINE_RWLOCK(snd_card_rwlock);
 int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
 #endif
 
+#ifdef CONFIG_PROC_FS
 static void snd_card_id_read(struct snd_info_entry *entry,
                             struct snd_info_buffer *buffer)
 {
        snd_iprintf(buffer, "%s\n", entry->card->id);
 }
 
+static inline int init_info_for_card(struct snd_card *card)
+{
+       int err;
+       struct snd_info_entry *entry;
+
+       if ((err = snd_info_card_register(card)) < 0) {
+               snd_printd("unable to create card info\n");
+               return err;
+       }
+       if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
+               snd_printd("unable to create card entry\n");
+               return err;
+       }
+       entry->c.text.read_size = PAGE_SIZE;
+       entry->c.text.read = snd_card_id_read;
+       if (snd_info_register(entry) < 0) {
+               snd_info_free_entry(entry);
+               entry = NULL;
+       }
+       card->proc_id = entry;
+       return 0;
+}
+#else /* !CONFIG_PROC_FS */
+#define init_info_for_card(card)
+#endif
+
 static void snd_card_free_thread(void * __card);
 
 /**
@@ -273,8 +300,7 @@ int snd_card_free(struct snd_card *card)
        }
        if (card->private_free)
                card->private_free(card);
-       if (card->proc_id)
-               snd_info_unregister(card->proc_id);
+       snd_info_unregister(card->proc_id);
        if (snd_info_card_free(card) < 0) {
                snd_printk(KERN_WARNING "unable to free card info\n");
                /* Not fatal error */
@@ -414,7 +440,6 @@ static void choose_default_id(struct snd_card *card)
 int snd_card_register(struct snd_card *card)
 {
        int err;
-       struct snd_info_entry *entry;
 
        snd_assert(card != NULL, return -EINVAL);
        if ((err = snd_device_register_all(card)) < 0)
@@ -429,22 +454,7 @@ int snd_card_register(struct snd_card *card)
                choose_default_id(card);
        snd_cards[card->number] = card;
        write_unlock(&snd_card_rwlock);
-       if ((err = snd_info_card_register(card)) < 0) {
-               snd_printd("unable to create card info\n");
-               goto __skip_info;
-       }
-       if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
-               snd_printd("unable to create card entry\n");
-               goto __skip_info;
-       }
-       entry->c.text.read_size = PAGE_SIZE;
-       entry->c.text.read = snd_card_id_read;
-       if (snd_info_register(entry) < 0) {
-               snd_info_free_entry(entry);
-               entry = NULL;
-       }
-       card->proc_id = entry;
-      __skip_info:
+       init_info_for_card(card);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
        if (snd_mixer_oss_notify_callback)
                snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
@@ -452,6 +462,7 @@ int snd_card_register(struct snd_card *card)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 static struct snd_info_entry *snd_card_info_entry = NULL;
 
 static void snd_card_info_read(struct snd_info_entry *entry,
@@ -478,7 +489,7 @@ static void snd_card_info_read(struct snd_info_entry *entry,
                snd_iprintf(buffer, "--- no soundcards ---\n");
 }
 
-#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
+#ifdef CONFIG_SND_OSSEMUL
 
 void snd_card_info_read_oss(struct snd_info_buffer *buffer)
 {
@@ -550,15 +561,15 @@ int __init snd_card_info_init(void)
 
 int __exit snd_card_info_done(void)
 {
-       if (snd_card_info_entry)
-               snd_info_unregister(snd_card_info_entry);
+       snd_info_unregister(snd_card_info_entry);
 #ifdef MODULE
-       if (snd_card_module_info_entry)
-               snd_info_unregister(snd_card_module_info_entry);
+       snd_info_unregister(snd_card_module_info_entry);
 #endif
        return 0;
 }
 
+#endif /* CONFIG_PROC_FS */
+
 /**
  *  snd_component_add - add a component string
  *  @card: soundcard structure
index 95036c83de43834eabce47b2c3df3da99158961d..28ca61eb0b0d9948515985a687e71e5543e9866e 100644 (file)
@@ -151,30 +151,6 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
 #define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
 #define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v 
 
-static char *snd_pcm_stream_names[] = {
-       STREAM(PLAYBACK),
-       STREAM(CAPTURE),
-};
-
-static char *snd_pcm_state_names[] = {
-       STATE(OPEN),
-       STATE(SETUP),
-       STATE(PREPARED),
-       STATE(RUNNING),
-       STATE(XRUN),
-       STATE(DRAINING),
-       STATE(PAUSED),
-       STATE(SUSPENDED),
-};
-
-static char *snd_pcm_access_names[] = {
-       ACCESS(MMAP_INTERLEAVED), 
-       ACCESS(MMAP_NONINTERLEAVED),
-       ACCESS(MMAP_COMPLEX),
-       ACCESS(RW_INTERLEAVED),
-       ACCESS(RW_NONINTERLEAVED),
-};
-
 static char *snd_pcm_format_names[] = {
        FORMAT(S8),
        FORMAT(U8),
@@ -216,6 +192,36 @@ static char *snd_pcm_format_names[] = {
        FORMAT(U18_3BE),
 };
 
+const char *snd_pcm_format_name(snd_pcm_format_t format)
+{
+       return snd_pcm_format_names[format];
+}
+
+#ifdef CONFIG_PROC_FS
+static char *snd_pcm_stream_names[] = {
+       STREAM(PLAYBACK),
+       STREAM(CAPTURE),
+};
+
+static char *snd_pcm_state_names[] = {
+       STATE(OPEN),
+       STATE(SETUP),
+       STATE(PREPARED),
+       STATE(RUNNING),
+       STATE(XRUN),
+       STATE(DRAINING),
+       STATE(PAUSED),
+       STATE(SUSPENDED),
+};
+
+static char *snd_pcm_access_names[] = {
+       ACCESS(MMAP_INTERLEAVED), 
+       ACCESS(MMAP_NONINTERLEAVED),
+       ACCESS(MMAP_COMPLEX),
+       ACCESS(RW_INTERLEAVED),
+       ACCESS(RW_NONINTERLEAVED),
+};
+
 static char *snd_pcm_subformat_names[] = {
        SUBFORMAT(STD), 
 };
@@ -236,11 +242,6 @@ static const char *snd_pcm_access_name(snd_pcm_access_t access)
        return snd_pcm_access_names[access];
 }
 
-const char *snd_pcm_format_name(snd_pcm_format_t format)
-{
-       return snd_pcm_format_names[format];
-}
-
 static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
 {
        return snd_pcm_subformat_names[subformat];
@@ -288,7 +289,6 @@ static const char *snd_pcm_oss_format_name(int format)
 }
 #endif
 
-#ifdef CONFIG_PROC_FS
 static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
                                   struct snd_info_buffer *buffer)
 {
@@ -431,7 +431,6 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
        snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);
        snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);
 }
-#endif
 
 #ifdef CONFIG_SND_DEBUG
 static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
@@ -596,6 +595,12 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
        }
        return 0;
 }
+#else /* !CONFIG_PROC_FS */
+static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
+static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
+#endif /* CONFIG_PROC_FS */
 
 /**
  * snd_pcm_new_stream - create a new PCM stream
@@ -1013,6 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
@@ -1039,18 +1045,12 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
        up(&register_mutex);
 }
 
-/*
- *  ENTRY functions
- */
-
 static struct snd_info_entry *snd_pcm_proc_entry = NULL;
 
-static int __init alsa_pcm_init(void)
+static void snd_pcm_proc_init(void)
 {
        struct snd_info_entry *entry;
 
-       snd_ctl_register_ioctl(snd_pcm_control_ioctl);
-       snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
        if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
                snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128,
                                      snd_pcm_proc_read);
@@ -1060,6 +1060,29 @@ static int __init alsa_pcm_init(void)
                }
        }
        snd_pcm_proc_entry = entry;
+}
+
+static void snd_pcm_proc_done(void)
+{
+       if (snd_pcm_proc_entry)
+               snd_info_unregister(snd_pcm_proc_entry);
+}
+
+#else /* !CONFIG_PROC_FS */
+#define snd_pcm_proc_init()
+#define snd_pcm_proc_done()
+#endif /* CONFIG_PROC_FS */
+
+
+/*
+ *  ENTRY functions
+ */
+
+static int __init alsa_pcm_init(void)
+{
+       snd_ctl_register_ioctl(snd_pcm_control_ioctl);
+       snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
+       snd_pcm_proc_init();
        return 0;
 }
 
@@ -1067,10 +1090,7 @@ static void __exit alsa_pcm_exit(void)
 {
        snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
        snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
-       if (snd_pcm_proc_entry) {
-               snd_info_unregister(snd_pcm_proc_entry);
-               snd_pcm_proc_entry = NULL;
-       }
+       snd_pcm_proc_done();
 }
 
 module_init(alsa_pcm_init)
index d37bcb76188482c4b9acb66c6388530117c293f3..a0119ae67dcd709fd870b986cb21ac4be2874ed6 100644 (file)
@@ -100,10 +100,8 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream
 int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
 {
        snd_pcm_lib_preallocate_dma_free(substream);
-       if (substream->proc_prealloc_entry) {
-               snd_info_unregister(substream->proc_prealloc_entry);
-               substream->proc_prealloc_entry = NULL;
-       }
+       snd_info_unregister(substream->proc_prealloc_entry);
+       substream->proc_prealloc_entry = NULL;
        return 0;
 }
 
@@ -126,6 +124,7 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  * read callback for prealloc proc file
  *
@@ -185,20 +184,10 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
        }
 }
 
-/*
- * pre-allocate the buffer and create a proc file for the substream
- */
-static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
-                                         size_t size, size_t max)
+static inline void preallocate_info_init(struct snd_pcm_substream *substream)
 {
        struct snd_info_entry *entry;
 
-       if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
-               preallocate_pcm_pages(substream, size);
-
-       if (substream->dma_buffer.bytes > 0)
-               substream->buffer_bytes_max = substream->dma_buffer.bytes;
-       substream->dma_max = max;
        if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
                entry->c.text.read_size = 64;
                entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
@@ -212,6 +201,26 @@ static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
                }
        }
        substream->proc_prealloc_entry = entry;
+}
+
+#else /* !CONFIG_PROC_FS */
+#define preallocate_info_init(s)
+#endif
+
+/*
+ * pre-allocate the buffer and create a proc file for the substream
+ */
+static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
+                                         size_t size, size_t max)
+{
+
+       if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
+               preallocate_pcm_pages(substream, size);
+
+       if (substream->dma_buffer.bytes > 0)
+               substream->buffer_bytes_max = substream->dma_buffer.bytes;
+       substream->dma_max = max;
+       preallocate_info_init(substream);
        return 0;
 }
 
index 3b91f180f6877a2b97eaf249444dbca0af0203a7..a8eda02bcf1c0fe886b922ac0b628f7152a52921 100644 (file)
@@ -320,6 +320,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
        return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  INFO PART
  */
@@ -396,6 +397,7 @@ int __exit snd_minor_info_done(void)
                snd_info_unregister(snd_minor_info_entry);
        return 0;
 }
+#endif /* CONFIG_PROC_FS */
 
 /*
  *  INIT PART
index 3ae1c0d7ffd086256d2ceece62395125a75e0e9e..d0be32b517c1567f99cdbd7e590958d1fe8c07bb 100644 (file)
@@ -244,11 +244,9 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
        up(&sound_oss_mutex);
 }
 
-#endif /* CONFIG_PROC_FS */
 
 int __init snd_minor_info_oss_init(void)
 {
-#ifdef CONFIG_PROC_FS
        struct snd_info_entry *entry;
 
        entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
@@ -261,17 +259,15 @@ int __init snd_minor_info_oss_init(void)
                }
        }
        snd_minor_info_oss_entry = entry;
-#endif
        return 0;
 }
 
 int __exit snd_minor_info_oss_done(void)
 {
-#ifdef CONFIG_PROC_FS
        if (snd_minor_info_oss_entry)
                snd_info_unregister(snd_minor_info_oss_entry);
-#endif
        return 0;
 }
+#endif /* CONFIG_PROC_FS */
 
 #endif /* CONFIG_SND_OSSEMUL */
index c62dbacdca1328f368181051f2b9e25629b26066..2425b971b240b01387a00f0cb0b3df08b51941bb 100644 (file)
@@ -1052,6 +1052,7 @@ static int snd_timer_register_system(void)
        return snd_timer_global_register(timer);
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
@@ -1107,6 +1108,33 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
        up(&register_mutex);
 }
 
+static struct snd_info_entry *snd_timer_proc_entry = NULL;
+
+static void __init snd_timer_proc_init(void)
+{
+       struct snd_info_entry *entry;
+
+       entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
+       if (entry != NULL) {
+               entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
+               entry->c.text.read = snd_timer_proc_read;
+               if (snd_info_register(entry) < 0) {
+                       snd_info_free_entry(entry);
+                       entry = NULL;
+               }
+       }
+       snd_timer_proc_entry = entry;
+}
+
+static void __exit snd_timer_proc_done(void)
+{
+       snd_info_unregister(snd_timer_proc_entry);
+}
+#else /* !CONFIG_PROC_FS */
+#define snd_timer_proc_init()
+#define snd_timer_proc_done()
+#endif
+
 /*
  *  USER SPACE interface
  */
@@ -1928,27 +1956,15 @@ static struct file_operations snd_timer_f_ops =
  *  ENTRY functions
  */
 
-static struct snd_info_entry *snd_timer_proc_entry = NULL;
-
 static int __init alsa_timer_init(void)
 {
        int err;
-       struct snd_info_entry *entry;
 
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
        snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
                              "system timer");
 #endif
-       entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
-       if (entry != NULL) {
-               entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
-               entry->c.text.read = snd_timer_proc_read;
-               if (snd_info_register(entry) < 0) {
-                       snd_info_free_entry(entry);
-                       entry = NULL;
-               }
-       }
-       snd_timer_proc_entry = entry;
+
        if ((err = snd_timer_register_system()) < 0)
                snd_printk(KERN_ERR "unable to register system timer (%i)\n",
                           err);
@@ -1956,6 +1972,7 @@ static int __init alsa_timer_init(void)
                                       &snd_timer_f_ops, NULL, "timer")) < 0)
                snd_printk(KERN_ERR "unable to register timer device (%i)\n",
                           err);
+       snd_timer_proc_init();
        return 0;
 }
 
@@ -1969,10 +1986,7 @@ static void __exit alsa_timer_exit(void)
                struct snd_timer *timer = list_entry(p, struct snd_timer, device_list);
                snd_timer_unregister(timer);
        }
-       if (snd_timer_proc_entry) {
-               snd_info_unregister(snd_timer_proc_entry);
-               snd_timer_proc_entry = NULL;
-       }
+       snd_timer_proc_done();
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
        snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
 #endif