Merge branch 'topic/hwdep-cleanup' into for-linus
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index d9eea01..8c05e47a 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -27,18 +27,28 @@
 
 struct snd_hwdep;
 
+/* hwdep file ops; all ops can be NULL */
 struct snd_hwdep_ops {
-	long long (*llseek) (struct snd_hwdep *hw, struct file * file, long long offset, int orig);
-	long (*read) (struct snd_hwdep *hw, char __user *buf, long count, loff_t *offset);
-	long (*write) (struct snd_hwdep *hw, const char __user *buf, long count, loff_t *offset);
-	int (*open) (struct snd_hwdep * hw, struct file * file);
-	int (*release) (struct snd_hwdep *hw, struct file * file);
-	unsigned int (*poll) (struct snd_hwdep *hw, struct file * file, poll_table * wait);
-	int (*ioctl) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg);
-	int (*ioctl_compat) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg);
-	int (*mmap) (struct snd_hwdep *hw, struct file * file, struct vm_area_struct * vma);
-	int (*dsp_status) (struct snd_hwdep *hw, struct snd_hwdep_dsp_status *status);
-	int (*dsp_load) (struct snd_hwdep *hw, struct snd_hwdep_dsp_image *image);
+	long long (*llseek)(struct snd_hwdep *hw, struct file *file,
+			    long long offset, int orig);
+	long (*read)(struct snd_hwdep *hw, char __user *buf,
+		     long count, loff_t *offset);
+	long (*write)(struct snd_hwdep *hw, const char __user *buf,
+		      long count, loff_t *offset);
+	int (*open)(struct snd_hwdep *hw, struct file * file);
+	int (*release)(struct snd_hwdep *hw, struct file * file);
+	unsigned int (*poll)(struct snd_hwdep *hw, struct file *file,
+			     poll_table *wait);
+	int (*ioctl)(struct snd_hwdep *hw, struct file *file,
+		     unsigned int cmd, unsigned long arg);
+	int (*ioctl_compat)(struct snd_hwdep *hw, struct file *file,
+			    unsigned int cmd, unsigned long arg);
+	int (*mmap)(struct snd_hwdep *hw, struct file *file,
+		    struct vm_area_struct *vma);
+	int (*dsp_status)(struct snd_hwdep *hw,
+			  struct snd_hwdep_dsp_status *status);
+	int (*dsp_load)(struct snd_hwdep *hw,
+			struct snd_hwdep_dsp_image *image);
 };
 
 struct snd_hwdep {
@@ -61,9 +71,9 @@
 	void (*private_free) (struct snd_hwdep *hwdep);
 
 	struct mutex open_mutex;
-	int used;
-	unsigned int dsp_loaded;
-	unsigned int exclusive: 1;
+	int used;			/* reference counter */
+	unsigned int dsp_loaded;	/* bit fields of loaded dsp indices */
+	unsigned int exclusive:1;	/* exclusive access mode */
 };
 
 extern int snd_hwdep_new(struct snd_card *card, char *id, int device,
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 195cafc..a70ee7f 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -99,9 +99,6 @@
 	if (hw == NULL)
 		return -ENODEV;
 
-	if (!hw->ops.open)
-		return -ENXIO;
-
 	if (!try_module_get(hw->card->module))
 		return -EFAULT;
 
@@ -113,6 +110,10 @@
 			err = -EBUSY;
 			break;
 		}
+		if (!hw->ops.open) {
+			err = 0;
+			break;
+		}
 		err = hw->ops.open(hw, file);
 		if (err >= 0)
 			break;
@@ -151,7 +152,7 @@
 
 static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
-	int err = -ENXIO;
+	int err = 0;
 	struct snd_hwdep *hw = file->private_data;
 	struct module *mod = hw->card->module;
 
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index 8d6362e..46df881 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -119,16 +119,6 @@
 
 #else /* old style firmware loading */
 
-static int vx_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
-static int vx_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
 static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
 			       struct snd_hwdep_dsp_status *info)
 {
@@ -243,8 +233,6 @@
 
 	hw->iface = SNDRV_HWDEP_IFACE_VX;
 	hw->private_data = chip;
-	hw->ops.open = vx_hwdep_open;
-	hw->ops.release = vx_hwdep_release;
 	hw->ops.dsp_status = vx_hwdep_dsp_status;
 	hw->ops.dsp_load = vx_hwdep_dsp_load;
 	hw->exclusive = 1;
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index 3782b52..fa4de98 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -581,16 +581,6 @@
 /* miXart hwdep interface id string */
 #define SND_MIXART_HWDEP_ID       "miXart Loader"
 
-static int mixart_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
-static int mixart_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
 static int mixart_hwdep_dsp_status(struct snd_hwdep *hw,
 				   struct snd_hwdep_dsp_status *info)
 {
@@ -643,8 +633,6 @@
 
 	hw->iface = SNDRV_HWDEP_IFACE_MIXART;
 	hw->private_data = mgr;
-	hw->ops.open = mixart_hwdep_open;
-	hw->ops.release = mixart_hwdep_release;
 	hw->ops.dsp_status = mixart_hwdep_dsp_status;
 	hw->ops.dsp_load = mixart_hwdep_dsp_load;
 	hw->exclusive = 1;
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 592743a..17cb123 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -471,16 +471,6 @@
 	return 0;
 }
 
-static int pcxhr_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
-static int pcxhr_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
 int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
 {
 	int err;
@@ -495,8 +485,6 @@
 
 	hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
 	hw->private_data = mgr;
-	hw->ops.open = pcxhr_hwdep_open;
-	hw->ops.release = pcxhr_hwdep_release;
 	hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
 	hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
 	hw->exclusive = 1;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 05b3f79..bacfdd1 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -4413,13 +4413,6 @@
 	return 0;
 }
 
-static int snd_hdsp_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
-{
-	/* we have nothing to initialize but the call is required */
-	return 0;
-}
-
-
 /* helper functions for copying meter values */
 static inline int copy_u32_le(void __user *dest, void __iomem *src)
 {
@@ -4738,9 +4731,7 @@
 	hw->private_data = hdsp;
 	strcpy(hw->name, "HDSP hwdep interface");
 
-	hw->ops.open = snd_hdsp_hwdep_dummy_op;
 	hw->ops.ioctl = snd_hdsp_hwdep_ioctl;
-	hw->ops.release = snd_hdsp_hwdep_dummy_op;
 		
 	return 0;
 }
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index d4b4e0d..bac2dc0 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -4100,13 +4100,6 @@
 	return 0;
 }
 
-static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep * hw, struct file *file)
-{
-	/* we have nothing to initialize but the call is required */
-	return 0;
-}
-
-
 static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
 				 unsigned int cmd, unsigned long arg)
 {
@@ -4213,9 +4206,7 @@
 	hw->private_data = hdspm;
 	strcpy(hw->name, "HDSPM hwdep interface");
 
-	hw->ops.open = snd_hdspm_hwdep_dummy_op;
 	hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
-	hw->ops.release = snd_hdspm_hwdep_dummy_op;
 
 	return 0;
 }
diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c
index 0a53914..ff0b2a8 100644
--- a/sound/synth/emux/emux_hwdep.c
+++ b/sound/synth/emux/emux_hwdep.c
@@ -24,25 +24,6 @@
 #include <asm/uaccess.h>
 #include "emux_voice.h"
 
-/*
- * open the hwdep device
- */
-static int
-snd_emux_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
-
-/*
- * close the device
- */
-static int
-snd_emux_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
 
 #define TMP_CLIENT_ID	0x1001
 
@@ -146,8 +127,6 @@
 	emu->hwdep = hw;
 	strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
 	hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE;
-	hw->ops.open = snd_emux_hwdep_open;
-	hw->ops.release = snd_emux_hwdep_release;
 	hw->ops.ioctl = snd_emux_hwdep_ioctl;
 	hw->exclusive = 1;
 	hw->private_data = emu;
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 00397c8..2bde792 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -78,7 +78,6 @@
 
 	/* Sound Blaster remote control stuff */
 	const struct rc_config *rc_cfg;
-	unsigned long rc_hwdep_open;
 	u32 rc_code;
 	wait_queue_head_t rc_waitq;
 	struct urb *rc_urb;
@@ -1797,24 +1796,6 @@
 	wake_up(&mixer->rc_waitq);
 }
 
-static int snd_usb_sbrc_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	struct usb_mixer_interface *mixer = hw->private_data;
-
-	if (test_and_set_bit(0, &mixer->rc_hwdep_open))
-		return -EBUSY;
-	return 0;
-}
-
-static int snd_usb_sbrc_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	struct usb_mixer_interface *mixer = hw->private_data;
-
-	clear_bit(0, &mixer->rc_hwdep_open);
-	smp_mb__after_clear_bit();
-	return 0;
-}
-
 static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
 				     long count, loff_t *offset)
 {
@@ -1867,9 +1848,8 @@
 	hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
 	hwdep->private_data = mixer;
 	hwdep->ops.read = snd_usb_sbrc_hwdep_read;
-	hwdep->ops.open = snd_usb_sbrc_hwdep_open;
-	hwdep->ops.release = snd_usb_sbrc_hwdep_release;
 	hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
+	hwdep->exclusive = 1;
 
 	mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!mixer->rc_urb)
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 1558a5c..a26d8d8 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -106,16 +106,6 @@
 }
 
 
-static int snd_usX2Y_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
-static int snd_usX2Y_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
-	return 0;
-}
-
 static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
 				      struct snd_hwdep_dsp_status *info)
 {
@@ -267,8 +257,6 @@
 
 	hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
 	hw->private_data = usX2Y(card);
-	hw->ops.open = snd_usX2Y_hwdep_open;
-	hw->ops.release = snd_usX2Y_hwdep_release;
 	hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status;
 	hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load;
 	hw->ops.mmap = snd_us428ctls_mmap;