aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h2
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c21
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c2
-rw-r--r--arch/s390/include/asm/qdio.h7
-rw-r--r--arch/s390/kernel/time.c10
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/mm/cmm.c2
-rw-r--r--drivers/char/hvc_iucv.c6
-rw-r--r--drivers/s390/block/dasd.c36
-rw-r--r--drivers/s390/block/dasd_3990_erp.c4
-rw-r--r--drivers/s390/block/dasd_devmap.c13
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_eckd.c27
-rw-r--r--drivers/s390/block/dasd_fba.c10
-rw-r--r--drivers/s390/block/dasd_genhd.c3
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_ioctl.c6
-rw-r--r--drivers/s390/cio/device.c5
-rw-r--r--drivers/s390/cio/qdio_debug.c1
-rw-r--r--drivers/s390/cio/qdio_main.c3
-rw-r--r--drivers/s390/net/Kconfig10
-rw-r--r--drivers/s390/net/Makefile1
-rw-r--r--drivers/s390/net/qeth_core_main.c3
-rw-r--r--drivers/s390/net/smsgiucv.c15
-rw-r--r--drivers/s390/net/smsgiucv.h8
-rw-r--r--drivers/s390/net/smsgiucv_app.c211
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
-rw-r--r--drivers/watchdog/Kconfig20
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/acquirewdt.c2
-rw-r--r--drivers/watchdog/advantechwdt.c2
-rw-r--r--drivers/watchdog/adx_wdt.c2
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/watchdog/ar7_wdt.c2
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/bcm47xx_wdt.c2
-rw-r--r--drivers/watchdog/bfin_wdt.c56
-rw-r--r--drivers/watchdog/booke_wdt.c2
-rw-r--r--drivers/watchdog/coh901327_wdt.c2
-rw-r--r--drivers/watchdog/cpu5wdt.c2
-rw-r--r--drivers/watchdog/cpwd.c2
-rw-r--r--drivers/watchdog/davinci_wdt.c2
-rw-r--r--drivers/watchdog/ep93xx_wdt.c2
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/gef_wdt.c16
-rw-r--r--drivers/watchdog/geodewdt.c2
-rw-r--r--drivers/watchdog/hpwdt.c2
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_wdt.c21
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/watchdog/indydog.c2
-rw-r--r--drivers/watchdog/it8712f_wdt.c2
-rw-r--r--drivers/watchdog/it87_wdt.c2
-rw-r--r--drivers/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/watchdog/ks8695_wdt.c2
-rw-r--r--drivers/watchdog/machzwd.c2
-rw-r--r--drivers/watchdog/max63xx_wdt.c397
-rw-r--r--drivers/watchdog/mixcomwd.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/watchdog/mv64x60_wdt.c2
-rw-r--r--drivers/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/watchdog/pcwd.c2
-rw-r--r--drivers/watchdog/pcwd_pci.c2
-rw-r--r--drivers/watchdog/pcwd_usb.c2
-rw-r--r--drivers/watchdog/pika_wdt.c2
-rw-r--r--drivers/watchdog/pnx833x_wdt.c2
-rw-r--r--drivers/watchdog/rc32434_wdt.c2
-rw-r--r--drivers/watchdog/rdc321x_wdt.c2
-rw-r--r--drivers/watchdog/riowd.c2
-rw-r--r--drivers/watchdog/sbc_fitpc2_wdt.c2
-rw-r--r--drivers/watchdog/sch311x_wdt.c2
-rw-r--r--drivers/watchdog/stmp3xxx_wdt.c2
-rw-r--r--drivers/watchdog/ts72xx_wdt.c520
-rw-r--r--drivers/watchdog/txx9wdt.c25
-rw-r--r--drivers/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wdrtas.c2
-rw-r--r--drivers/watchdog/wdt.c2
-rw-r--r--drivers/watchdog/wdt_pci.c2
-rw-r--r--drivers/watchdog/wm831x_wdt.c2
-rw-r--r--drivers/watchdog/wm8350_wdt.c2
-rw-r--r--fs/fscache/Kconfig1
-rw-r--r--include/linux/usb/audio.h2
-rw-r--r--include/sound/asound.h2
-rw-r--r--sound/core/timer.c2
-rw-r--r--sound/isa/opti9xx/miro.c2
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c120
-rw-r--r--sound/isa/sb/jazz16.c1
-rw-r--r--sound/oss/coproc.h2
-rw-r--r--sound/oss/v_midi.h5
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_codec.c69
-rw-r--r--sound/pci/hda/hda_eld.c6
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_hdmi.c849
-rw-r--r--sound/pci/hda/patch_intelhdmi.c821
-rw-r--r--sound/pci/hda/patch_nvhdmi.c275
-rw-r--r--sound/pci/hda/patch_realtek.c10
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c2
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/soc/codecs/ak4104.c6
-rw-r--r--sound/soc/soc-core.c14
-rw-r--r--sound/usb/Kconfig6
-rw-r--r--sound/usb/caiaq/midi.h2
-rw-r--r--sound/usb/ua101.c100
-rw-r--r--sound/usb/usbaudio.c57
-rw-r--r--sound/usb/usbaudio.h3
-rw-r--r--sound/usb/usbquirks.h30
114 files changed, 2714 insertions, 1376 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 33df82e3a398..bfcbbf88c44d 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -1812,7 +1812,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
1812 Module snd-ua101 1812 Module snd-ua101
1813 ---------------- 1813 ----------------
1814 1814
1815 Module for the Edirol UA-101 audio/MIDI interface. 1815 Module for the Edirol UA-101/UA-1000 audio/MIDI interfaces.
1816 1816
1817 This module supports multiple devices, autoprobe and hotplugging. 1817 This module supports multiple devices, autoprobe and hotplugging.
1818 1818
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 3bd934e9a7f1..93107d88ff3a 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -65,6 +65,8 @@
65#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000 65#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
66#define TS72XX_RTC_DATA_SIZE 0x00001000 66#define TS72XX_RTC_DATA_SIZE 0x00001000
67 67
68#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
69#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
68 70
69#ifndef __ASSEMBLY__ 71#ifndef __ASSEMBLY__
70 72
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 259f7822ba52..fac1ec7a60fb 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -166,6 +166,26 @@ static struct platform_device ts72xx_rtc_device = {
166 .num_resources = 0, 166 .num_resources = 0,
167}; 167};
168 168
169static struct resource ts72xx_wdt_resources[] = {
170 {
171 .start = TS72XX_WDT_CONTROL_PHYS_BASE,
172 .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
173 .flags = IORESOURCE_MEM,
174 },
175 {
176 .start = TS72XX_WDT_FEED_PHYS_BASE,
177 .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
178 .flags = IORESOURCE_MEM,
179 },
180};
181
182static struct platform_device ts72xx_wdt_device = {
183 .name = "ts72xx-wdt",
184 .id = -1,
185 .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
186 .resource = ts72xx_wdt_resources,
187};
188
169static struct ep93xx_eth_data ts72xx_eth_data = { 189static struct ep93xx_eth_data ts72xx_eth_data = {
170 .phy_id = 1, 190 .phy_id = 1,
171}; 191};
@@ -175,6 +195,7 @@ static void __init ts72xx_init_machine(void)
175 ep93xx_init_devices(); 195 ep93xx_init_devices();
176 ts72xx_register_flash(); 196 ts72xx_register_flash();
177 platform_device_register(&ts72xx_rtc_device); 197 platform_device_register(&ts72xx_rtc_device);
198 platform_device_register(&ts72xx_wdt_device);
178 199
179 ep93xx_register_eth(&ts72xx_eth_data, 1); 200 ep93xx_register_eth(&ts72xx_eth_data, 1);
180} 201}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 6f8ebe1085b3..072b948b2e2d 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -553,7 +553,7 @@ static ssize_t mpc52xx_wdt_write(struct file *file, const char __user *data,
553 return 0; 553 return 0;
554} 554}
555 555
556static struct watchdog_info mpc5200_wdt_info = { 556static const struct watchdog_info mpc5200_wdt_info = {
557 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 557 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
558 .identity = WDT_IDENTITY, 558 .identity = WDT_IDENTITY,
559}; 559};
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index c666bfe5e984..9b04b1102bbc 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -321,11 +321,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
321#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 321#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
322#define QDIO_ERROR_SLSB_STATE 0x80 322#define QDIO_ERROR_SLSB_STATE 0x80
323 323
324/* for qdio_initialize */
325#define QDIO_INBOUND_0COPY_SBALS 0x01
326#define QDIO_OUTBOUND_0COPY_SBALS 0x02
327#define QDIO_USE_OUTBOUND_PCIS 0x04
328
329/* for qdio_cleanup */ 324/* for qdio_cleanup */
330#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 325#define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01
331#define QDIO_FLAG_CLEANUP_USING_HALT 0x02 326#define QDIO_FLAG_CLEANUP_USING_HALT 0x02
@@ -344,7 +339,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
344 * @input_handler: handler to be called for input queues 339 * @input_handler: handler to be called for input queues
345 * @output_handler: handler to be called for output queues 340 * @output_handler: handler to be called for output queues
346 * @int_parm: interruption parameter 341 * @int_parm: interruption parameter
347 * @flags: initialization flags
348 * @input_sbal_addr_array: address of no_input_qs * 128 pointers 342 * @input_sbal_addr_array: address of no_input_qs * 128 pointers
349 * @output_sbal_addr_array: address of no_output_qs * 128 pointers 343 * @output_sbal_addr_array: address of no_output_qs * 128 pointers
350 */ 344 */
@@ -361,7 +355,6 @@ struct qdio_initialize {
361 qdio_handler_t *input_handler; 355 qdio_handler_t *input_handler;
362 qdio_handler_t *output_handler; 356 qdio_handler_t *output_handler;
363 unsigned long int_parm; 357 unsigned long int_parm;
364 unsigned long flags;
365 void **input_sbal_addr_array; 358 void **input_sbal_addr_array;
366 void **output_sbal_addr_array; 359 void **output_sbal_addr_array;
367}; 360};
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 75894c281710..aa2483e460f3 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -73,15 +73,15 @@ unsigned long long monotonic_clock(void)
73} 73}
74EXPORT_SYMBOL(monotonic_clock); 74EXPORT_SYMBOL(monotonic_clock);
75 75
76void tod_to_timeval(__u64 todval, struct timespec *xtime) 76void tod_to_timeval(__u64 todval, struct timespec *xt)
77{ 77{
78 unsigned long long sec; 78 unsigned long long sec;
79 79
80 sec = todval >> 12; 80 sec = todval >> 12;
81 do_div(sec, 1000000); 81 do_div(sec, 1000000);
82 xtime->tv_sec = sec; 82 xt->tv_sec = sec;
83 todval -= (sec * 1000000) << 12; 83 todval -= (sec * 1000000) << 12;
84 xtime->tv_nsec = ((todval * 1000) >> 12); 84 xt->tv_nsec = ((todval * 1000) >> 12);
85} 85}
86EXPORT_SYMBOL(tod_to_timeval); 86EXPORT_SYMBOL(tod_to_timeval);
87 87
@@ -216,8 +216,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
216 ++vdso_data->tb_update_count; 216 ++vdso_data->tb_update_count;
217 smp_wmb(); 217 smp_wmb();
218 vdso_data->xtime_tod_stamp = clock->cycle_last; 218 vdso_data->xtime_tod_stamp = clock->cycle_last;
219 vdso_data->xtime_clock_sec = xtime.tv_sec; 219 vdso_data->xtime_clock_sec = wall_time->tv_sec;
220 vdso_data->xtime_clock_nsec = xtime.tv_nsec; 220 vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
221 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; 221 vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
222 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; 222 vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
223 smp_wmb(); 223 smp_wmb();
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index cd54a1c352af..761ab8b56afc 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -2,7 +2,8 @@
2# Makefile for s390-specific library files.. 2# Makefile for s390-specific library files..
3# 3#
4 4
5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o usercopy.o 5lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
6obj-y += usercopy.o
6obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o 7obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o
7lib-$(CONFIG_64BIT) += uaccess_mvcos.o 8lib-$(CONFIG_64BIT) += uaccess_mvcos.o
8lib-$(CONFIG_SMP) += spinlock.o 9lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 76a3637b88e0..f16bd04e39e9 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -374,7 +374,7 @@ static struct ctl_table cmm_dir_table[] = {
374#ifdef CONFIG_CMM_IUCV 374#ifdef CONFIG_CMM_IUCV
375#define SMSG_PREFIX "CMM" 375#define SMSG_PREFIX "CMM"
376static void 376static void
377cmm_smsg_target(char *from, char *msg) 377cmm_smsg_target(const char *from, char *msg)
378{ 378{
379 long nr, seconds; 379 long nr, seconds;
380 380
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index 21681a81cc35..37b0542a4eeb 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -139,6 +139,8 @@ struct hvc_iucv_private *hvc_iucv_get_private(uint32_t num)
139 * 139 *
140 * This function allocates a new struct iucv_tty_buffer element and, optionally, 140 * This function allocates a new struct iucv_tty_buffer element and, optionally,
141 * allocates an internal data buffer with the specified size @size. 141 * allocates an internal data buffer with the specified size @size.
142 * The internal data buffer is always allocated with GFP_DMA which is
143 * required for receiving and sending data with IUCV.
142 * Note: The total message size arises from the internal buffer size and the 144 * Note: The total message size arises from the internal buffer size and the
143 * members of the iucv_tty_msg structure. 145 * members of the iucv_tty_msg structure.
144 * The function returns NULL if memory allocation has failed. 146 * The function returns NULL if memory allocation has failed.
@@ -154,7 +156,7 @@ static struct iucv_tty_buffer *alloc_tty_buffer(size_t size, gfp_t flags)
154 156
155 if (size > 0) { 157 if (size > 0) {
156 bufp->msg.length = MSG_SIZE(size); 158 bufp->msg.length = MSG_SIZE(size);
157 bufp->mbuf = kmalloc(bufp->msg.length, flags); 159 bufp->mbuf = kmalloc(bufp->msg.length, flags | GFP_DMA);
158 if (!bufp->mbuf) { 160 if (!bufp->mbuf) {
159 mempool_free(bufp, hvc_iucv_mempool); 161 mempool_free(bufp, hvc_iucv_mempool);
160 return NULL; 162 return NULL;
@@ -237,7 +239,7 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv,
237 if (!rb->mbuf) { /* message not yet received ... */ 239 if (!rb->mbuf) { /* message not yet received ... */
238 /* allocate mem to store msg data; if no memory is available 240 /* allocate mem to store msg data; if no memory is available
239 * then leave the buffer on the list and re-try later */ 241 * then leave the buffer on the list and re-try later */
240 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC); 242 rb->mbuf = kmalloc(rb->msg.length, GFP_ATOMIC | GFP_DMA);
241 if (!rb->mbuf) 243 if (!rb->mbuf)
242 return -ENOMEM; 244 return -ENOMEM;
243 245
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 4951aa82e9f5..bbea90baf98f 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -26,6 +26,7 @@
26#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
27#include <asm/idals.h> 27#include <asm/idals.h>
28#include <asm/itcw.h> 28#include <asm/itcw.h>
29#include <asm/diag.h>
29 30
30/* This is ugly... */ 31/* This is ugly... */
31#define PRINTK_HEADER "dasd:" 32#define PRINTK_HEADER "dasd:"
@@ -2212,6 +2213,13 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
2212 goto out; 2213 goto out;
2213 } 2214 }
2214 2215
2216 if ((mode & FMODE_WRITE) &&
2217 (test_bit(DASD_FLAG_DEVICE_RO, &base->flags) ||
2218 (base->features & DASD_FEATURE_READONLY))) {
2219 rc = -EROFS;
2220 goto out;
2221 }
2222
2215 return 0; 2223 return 0;
2216 2224
2217out: 2225out:
@@ -2289,6 +2297,34 @@ dasd_exit(void)
2289 * SECTION: common functions for ccw_driver use 2297 * SECTION: common functions for ccw_driver use
2290 */ 2298 */
2291 2299
2300/*
2301 * Is the device read-only?
2302 * Note that this function does not report the setting of the
2303 * readonly device attribute, but how it is configured in z/VM.
2304 */
2305int dasd_device_is_ro(struct dasd_device *device)
2306{
2307 struct ccw_dev_id dev_id;
2308 struct diag210 diag_data;
2309 int rc;
2310
2311 if (!MACHINE_IS_VM)
2312 return 0;
2313 ccw_device_get_id(device->cdev, &dev_id);
2314 memset(&diag_data, 0, sizeof(diag_data));
2315 diag_data.vrdcdvno = dev_id.devno;
2316 diag_data.vrdclen = sizeof(diag_data);
2317 rc = diag210(&diag_data);
2318 if (rc == 0 || rc == 2) {
2319 return diag_data.vrdcvfla & 0x80;
2320 } else {
2321 DBF_EVENT(DBF_WARNING, "diag210 failed for dev=%04x with rc=%d",
2322 dev_id.devno, rc);
2323 return 0;
2324 }
2325}
2326EXPORT_SYMBOL_GPL(dasd_device_is_ro);
2327
2292static void dasd_generic_auto_online(void *data, async_cookie_t cookie) 2328static void dasd_generic_auto_online(void *data, async_cookie_t cookie)
2293{ 2329{
2294 struct ccw_device *cdev = data; 2330 struct ccw_device *cdev = data;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 44796ba4eb9b..51224f76b980 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1045,6 +1045,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1045 1045
1046 erp->retries = 5; 1046 erp->retries = 5;
1047 1047
1048 } else if (sense[1] & SNS1_WRITE_INHIBITED) {
1049 dev_err(&device->cdev->dev, "An I/O request was rejected"
1050 " because writing is inhibited\n");
1051 erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
1048 } else { 1052 } else {
1049 /* fatal error - set status to FAILED 1053 /* fatal error - set status to FAILED
1050 internal error 09 - Command Reject */ 1054 internal error 09 - Command Reject */
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index d49766f3b940..8e23919c8704 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -742,6 +742,7 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
742 const char *buf, size_t count) 742 const char *buf, size_t count)
743{ 743{
744 struct dasd_devmap *devmap; 744 struct dasd_devmap *devmap;
745 struct dasd_device *device;
745 int val; 746 int val;
746 char *endp; 747 char *endp;
747 748
@@ -758,12 +759,14 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
758 devmap->features |= DASD_FEATURE_READONLY; 759 devmap->features |= DASD_FEATURE_READONLY;
759 else 760 else
760 devmap->features &= ~DASD_FEATURE_READONLY; 761 devmap->features &= ~DASD_FEATURE_READONLY;
761 if (devmap->device) 762 device = devmap->device;
762 devmap->device->features = devmap->features; 763 if (device) {
763 if (devmap->device && devmap->device->block 764 device->features = devmap->features;
764 && devmap->device->block->gdp) 765 val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
765 set_disk_ro(devmap->device->block->gdp, val); 766 }
766 spin_unlock(&dasd_devmap_lock); 767 spin_unlock(&dasd_devmap_lock);
768 if (device && device->block && device->block->gdp)
769 set_disk_ro(device->block->gdp, val);
767 return count; 770 return count;
768} 771}
769 772
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 6e14863f5c70..687f323cdc38 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -145,12 +145,10 @@ dasd_diag_erp(struct dasd_device *device)
145 mdsk_term_io(device); 145 mdsk_term_io(device);
146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); 146 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
147 if (rc == 4) { 147 if (rc == 4) {
148 if (!(device->features & DASD_FEATURE_READONLY)) { 148 if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
149 pr_warning("%s: The access mode of a DIAG device " 149 pr_warning("%s: The access mode of a DIAG device "
150 "changed to read-only\n", 150 "changed to read-only\n",
151 dev_name(&device->cdev->dev)); 151 dev_name(&device->cdev->dev));
152 device->features |= DASD_FEATURE_READONLY;
153 }
154 rc = 0; 152 rc = 0;
155 } 153 }
156 if (rc) 154 if (rc)
@@ -449,7 +447,7 @@ dasd_diag_check_device(struct dasd_device *device)
449 rc = -EIO; 447 rc = -EIO;
450 } else { 448 } else {
451 if (rc == 4) 449 if (rc == 4)
452 device->features |= DASD_FEATURE_READONLY; 450 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
453 pr_info("%s: New DASD with %ld byte/block, total size %ld " 451 pr_info("%s: New DASD with %ld byte/block, total size %ld "
454 "KB%s\n", dev_name(&device->cdev->dev), 452 "KB%s\n", dev_name(&device->cdev->dev),
455 (unsigned long) block->bp_block, 453 (unsigned long) block->bp_block,
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 1cca21aafaba..01f4e7a34aa8 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1089,6 +1089,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1089 struct dasd_eckd_private *private; 1089 struct dasd_eckd_private *private;
1090 struct dasd_block *block; 1090 struct dasd_block *block;
1091 int is_known, rc; 1091 int is_known, rc;
1092 int readonly;
1092 1093
1093 if (!ccw_device_is_pathgroup(device->cdev)) { 1094 if (!ccw_device_is_pathgroup(device->cdev)) {
1094 dev_warn(&device->cdev->dev, 1095 dev_warn(&device->cdev->dev,
@@ -1182,15 +1183,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1182 else 1183 else
1183 private->real_cyl = private->rdc_data.no_cyl; 1184 private->real_cyl = private->rdc_data.no_cyl;
1184 1185
1186 readonly = dasd_device_is_ro(device);
1187 if (readonly)
1188 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
1189
1185 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) " 1190 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
1186 "with %d cylinders, %d heads, %d sectors\n", 1191 "with %d cylinders, %d heads, %d sectors%s\n",
1187 private->rdc_data.dev_type, 1192 private->rdc_data.dev_type,
1188 private->rdc_data.dev_model, 1193 private->rdc_data.dev_model,
1189 private->rdc_data.cu_type, 1194 private->rdc_data.cu_type,
1190 private->rdc_data.cu_model.model, 1195 private->rdc_data.cu_model.model,
1191 private->real_cyl, 1196 private->real_cyl,
1192 private->rdc_data.trk_per_cyl, 1197 private->rdc_data.trk_per_cyl,
1193 private->rdc_data.sec_per_trk); 1198 private->rdc_data.sec_per_trk,
1199 readonly ? ", read-only device" : "");
1194 return 0; 1200 return 0;
1195 1201
1196out_err3: 1202out_err3:
@@ -2839,8 +2845,13 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2839 char *psf_data, *rssd_result; 2845 char *psf_data, *rssd_result;
2840 struct dasd_ccw_req *cqr; 2846 struct dasd_ccw_req *cqr;
2841 struct ccw1 *ccw; 2847 struct ccw1 *ccw;
2848 char psf0, psf1;
2842 int rc; 2849 int rc;
2843 2850
2851 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
2852 return -EACCES;
2853 psf0 = psf1 = 0;
2854
2844 /* Copy parms from caller */ 2855 /* Copy parms from caller */
2845 rc = -EFAULT; 2856 rc = -EFAULT;
2846 if (copy_from_user(&usrparm, argp, sizeof(usrparm))) 2857 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
@@ -2869,12 +2880,8 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
2869 (void __user *)(unsigned long) usrparm.psf_data, 2880 (void __user *)(unsigned long) usrparm.psf_data,
2870 usrparm.psf_data_len)) 2881 usrparm.psf_data_len))
2871 goto out_free; 2882 goto out_free;
2872 2883 psf0 = psf_data[0];
2873 /* sanity check on syscall header */ 2884 psf1 = psf_data[1];
2874 if (psf_data[0] != 0x17 && psf_data[1] != 0xce) {
2875 rc = -EINVAL;
2876 goto out_free;
2877 }
2878 2885
2879 /* setup CCWs for PSF + RSSD */ 2886 /* setup CCWs for PSF + RSSD */
2880 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device); 2887 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 , 0, device);
@@ -2925,7 +2932,9 @@ out_free:
2925 kfree(rssd_result); 2932 kfree(rssd_result);
2926 kfree(psf_data); 2933 kfree(psf_data);
2927out: 2934out:
2928 DBF_DEV_EVENT(DBF_WARNING, device, "Symmetrix ioctl: rc=%d", rc); 2935 DBF_DEV_EVENT(DBF_WARNING, device,
2936 "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",
2937 (int) psf0, (int) psf1, rc);
2929 return rc; 2938 return rc;
2930} 2939}
2931 2940
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 0f152444ac77..37282b90eecc 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -124,6 +124,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
124 struct dasd_fba_private *private; 124 struct dasd_fba_private *private;
125 struct ccw_device *cdev = device->cdev; 125 struct ccw_device *cdev = device->cdev;
126 int rc; 126 int rc;
127 int readonly;
127 128
128 private = (struct dasd_fba_private *) device->private; 129 private = (struct dasd_fba_private *) device->private;
129 if (!private) { 130 if (!private) {
@@ -162,16 +163,21 @@ dasd_fba_check_characteristics(struct dasd_device *device)
162 return rc; 163 return rc;
163 } 164 }
164 165
166 readonly = dasd_device_is_ro(device);
167 if (readonly)
168 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
169
165 dev_info(&device->cdev->dev, 170 dev_info(&device->cdev->dev,
166 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " 171 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
167 "and %d B/blk\n", 172 "and %d B/blk%s\n",
168 cdev->id.dev_type, 173 cdev->id.dev_type,
169 cdev->id.dev_model, 174 cdev->id.dev_model,
170 cdev->id.cu_type, 175 cdev->id.cu_type,
171 cdev->id.cu_model, 176 cdev->id.cu_model,
172 ((private->rdc_data.blk_bdsa * 177 ((private->rdc_data.blk_bdsa *
173 (private->rdc_data.blk_size >> 9)) >> 11), 178 (private->rdc_data.blk_size >> 9)) >> 11),
174 private->rdc_data.blk_size); 179 private->rdc_data.blk_size,
180 readonly ? ", read-only device" : "");
175 return 0; 181 return 0;
176} 182}
177 183
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 94f92a1247f2..30a1ca3d08b7 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -70,7 +70,8 @@ int dasd_gendisk_alloc(struct dasd_block *block)
70 } 70 }
71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26)); 71 len += sprintf(gdp->disk_name + len, "%c", 'a'+(base->devindex%26));
72 72
73 if (block->base->features & DASD_FEATURE_READONLY) 73 if (base->features & DASD_FEATURE_READONLY ||
74 test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
74 set_disk_ro(gdp, 1); 75 set_disk_ro(gdp, 1);
75 gdp->private_data = block; 76 gdp->private_data = block;
76 gdp->queue = block->request_queue; 77 gdp->queue = block->request_queue;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index ed73ce550822..a91d4a97d4f2 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -436,6 +436,10 @@ struct dasd_block {
436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 436#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */ 437#define DASD_FLAG_EER_SNSS 4 /* A SNSS is required */
438#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */ 438#define DASD_FLAG_EER_IN_USE 5 /* A SNSS request is running */
439#define DASD_FLAG_DEVICE_RO 6 /* The device itself is read-only. Don't
440 * confuse this with the user specified
441 * read-only feature.
442 */
439 443
440void dasd_put_device_wake(struct dasd_device *); 444void dasd_put_device_wake(struct dasd_device *);
441 445
@@ -609,6 +613,9 @@ char *dasd_get_sense(struct irb *);
609void dasd_device_set_stop_bits(struct dasd_device *, int); 613void dasd_device_set_stop_bits(struct dasd_device *, int);
610void dasd_device_remove_stop_bits(struct dasd_device *, int); 614void dasd_device_remove_stop_bits(struct dasd_device *, int);
611 615
616int dasd_device_is_ro(struct dasd_device *);
617
618
612/* externals in dasd_devmap.c */ 619/* externals in dasd_devmap.c */
613extern int dasd_max_devindex; 620extern int dasd_max_devindex;
614extern int dasd_probeonly; 621extern int dasd_probeonly;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 7039d9cf0fb4..3479f8158a1b 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -199,7 +199,8 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
199 if (!argp) 199 if (!argp)
200 return -EINVAL; 200 return -EINVAL;
201 201
202 if (block->base->features & DASD_FEATURE_READONLY) 202 if (block->base->features & DASD_FEATURE_READONLY ||
203 test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
203 return -EROFS; 204 return -EROFS;
204 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) 205 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
205 return -EFAULT; 206 return -EFAULT;
@@ -349,7 +350,8 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
349 return -EINVAL; 350 return -EINVAL;
350 if (get_user(intval, (int __user *)argp)) 351 if (get_user(intval, (int __user *)argp))
351 return -EFAULT; 352 return -EFAULT;
352 353 if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags))
354 return -EROFS;
353 set_disk_ro(bdev->bd_disk, intval); 355 set_disk_ro(bdev->bd_disk, intval);
354 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); 356 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval);
355} 357}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c6abb75c4615..6d229f3523a0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -764,7 +764,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch)
764static void io_subchannel_register(struct ccw_device *cdev) 764static void io_subchannel_register(struct ccw_device *cdev)
765{ 765{
766 struct subchannel *sch; 766 struct subchannel *sch;
767 int ret; 767 int ret, adjust_init_count = 1;
768 unsigned long flags; 768 unsigned long flags;
769 769
770 sch = to_subchannel(cdev->dev.parent); 770 sch = to_subchannel(cdev->dev.parent);
@@ -793,6 +793,7 @@ static void io_subchannel_register(struct ccw_device *cdev)
793 cdev->private->dev_id.ssid, 793 cdev->private->dev_id.ssid,
794 cdev->private->dev_id.devno); 794 cdev->private->dev_id.devno);
795 } 795 }
796 adjust_init_count = 0;
796 goto out; 797 goto out;
797 } 798 }
798 /* 799 /*
@@ -818,7 +819,7 @@ out:
818 cdev->private->flags.recog_done = 1; 819 cdev->private->flags.recog_done = 1;
819 wake_up(&cdev->private->wait_q); 820 wake_up(&cdev->private->wait_q);
820out_err: 821out_err:
821 if (atomic_dec_and_test(&ccw_device_init_count)) 822 if (adjust_init_count && atomic_dec_and_test(&ccw_device_init_count))
822 wake_up(&ccw_device_init_wq); 823 wake_up(&ccw_device_init_wq);
823} 824}
824 825
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index c94eb2a0fa2e..6ce83f56d537 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -33,7 +33,6 @@ void qdio_allocate_dbf(struct qdio_initialize *init_data,
33 DBF_HEX(&init_data->input_handler, sizeof(void *)); 33 DBF_HEX(&init_data->input_handler, sizeof(void *));
34 DBF_HEX(&init_data->output_handler, sizeof(void *)); 34 DBF_HEX(&init_data->output_handler, sizeof(void *));
35 DBF_HEX(&init_data->int_parm, sizeof(long)); 35 DBF_HEX(&init_data->int_parm, sizeof(long));
36 DBF_HEX(&init_data->flags, sizeof(long));
37 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); 36 DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
38 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); 37 DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
39 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); 38 DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 232ef047ba34..4f8f74311778 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -588,10 +588,11 @@ static void qdio_kick_handler(struct qdio_q *q)
588 if (q->is_input_q) { 588 if (q->is_input_q) {
589 qperf_inc(q, inbound_handler); 589 qperf_inc(q, inbound_handler);
590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 590 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
591 } else 591 } else {
592 qperf_inc(q, outbound_handler); 592 qperf_inc(q, outbound_handler);
593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 593 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
594 start, count); 594 start, count);
595 }
595 596
596 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 597 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
597 q->irq_ptr->int_parm); 598 q->irq_ptr->int_parm);
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index cb909a5b5047..977bb4d4ed15 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -43,6 +43,16 @@ config SMSGIUCV
43 Select this option if you want to be able to receive SMSG messages 43 Select this option if you want to be able to receive SMSG messages
44 from other VM guest systems. 44 from other VM guest systems.
45 45
46config SMSGIUCV_EVENT
47 tristate "Deliver IUCV special messages as uevents (VM only)"
48 depends on SMSGIUCV
49 help
50 Select this option to deliver CP special messages (SMSGs) as
51 uevents. The driver handles only those special messages that
52 start with "APP".
53
54 To compile as a module, choose M. The module name is "smsgiucv_app".
55
46config CLAW 56config CLAW
47 tristate "CLAW device support" 57 tristate "CLAW device support"
48 depends on CCW && NETDEVICES 58 depends on CCW && NETDEVICES
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6cab5a62f99e..4dfe8c1092da 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -6,6 +6,7 @@ ctcm-y += ctcm_main.o ctcm_fsms.o ctcm_mpc.o ctcm_sysfs.o ctcm_dbug.o
6obj-$(CONFIG_CTCM) += ctcm.o fsm.o 6obj-$(CONFIG_CTCM) += ctcm.o fsm.o
7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o 7obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 8obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
9obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o
9obj-$(CONFIG_LCS) += lcs.o 10obj-$(CONFIG_LCS) += lcs.o
10obj-$(CONFIG_CLAW) += claw.o 11obj-$(CONFIG_CLAW) += claw.o
11qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index fa8a519218ac..7d25bdd443cd 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3805,9 +3805,6 @@ static int qeth_qdio_establish(struct qeth_card *card)
3805 init_data.input_handler = card->discipline.input_handler; 3805 init_data.input_handler = card->discipline.input_handler;
3806 init_data.output_handler = card->discipline.output_handler; 3806 init_data.output_handler = card->discipline.output_handler;
3807 init_data.int_parm = (unsigned long) card; 3807 init_data.int_parm = (unsigned long) card;
3808 init_data.flags = QDIO_INBOUND_0COPY_SBALS |
3809 QDIO_OUTBOUND_0COPY_SBALS |
3810 QDIO_USE_OUTBOUND_PCIS;
3811 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 3808 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3812 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 3809 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
3813 3810
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 67f2485d2372..ecef1edee701 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -31,9 +31,9 @@
31 31
32struct smsg_callback { 32struct smsg_callback {
33 struct list_head list; 33 struct list_head list;
34 char *prefix; 34 const char *prefix;
35 int len; 35 int len;
36 void (*callback)(char *from, char *str); 36 void (*callback)(const char *from, char *str);
37}; 37};
38 38
39MODULE_AUTHOR 39MODULE_AUTHOR
@@ -100,8 +100,8 @@ static void smsg_message_pending(struct iucv_path *path,
100 kfree(buffer); 100 kfree(buffer);
101} 101}
102 102
103int smsg_register_callback(char *prefix, 103int smsg_register_callback(const char *prefix,
104 void (*callback)(char *from, char *str)) 104 void (*callback)(const char *from, char *str))
105{ 105{
106 struct smsg_callback *cb; 106 struct smsg_callback *cb;
107 107
@@ -117,8 +117,9 @@ int smsg_register_callback(char *prefix,
117 return 0; 117 return 0;
118} 118}
119 119
120void smsg_unregister_callback(char *prefix, 120void smsg_unregister_callback(const char *prefix,
121 void (*callback)(char *from, char *str)) 121 void (*callback)(const char *from,
122 char *str))
122{ 123{
123 struct smsg_callback *cb, *tmp; 124 struct smsg_callback *cb, *tmp;
124 125
@@ -176,7 +177,7 @@ static const struct dev_pm_ops smsg_pm_ops = {
176 177
177static struct device_driver smsg_driver = { 178static struct device_driver smsg_driver = {
178 .owner = THIS_MODULE, 179 .owner = THIS_MODULE,
179 .name = "SMSGIUCV", 180 .name = SMSGIUCV_DRV_NAME,
180 .bus = &iucv_bus, 181 .bus = &iucv_bus,
181 .pm = &smsg_pm_ops, 182 .pm = &smsg_pm_ops,
182}; 183};
diff --git a/drivers/s390/net/smsgiucv.h b/drivers/s390/net/smsgiucv.h
index 67f5d4f8378d..149a1151608d 100644
--- a/drivers/s390/net/smsgiucv.h
+++ b/drivers/s390/net/smsgiucv.h
@@ -5,6 +5,10 @@
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 */ 6 */
7 7
8int smsg_register_callback(char *, void (*)(char *, char *)); 8#define SMSGIUCV_DRV_NAME "SMSGIUCV"
9void smsg_unregister_callback(char *, void (*)(char *, char *)); 9
10int smsg_register_callback(const char *,
11 void (*)(const char *, char *));
12void smsg_unregister_callback(const char *,
13 void (*)(const char *, char *));
10 14
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
new file mode 100644
index 000000000000..91579dc6a2b0
--- /dev/null
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -0,0 +1,211 @@
1/*
2 * Deliver z/VM CP special messages (SMSG) as uevents.
3 *
4 * The driver registers for z/VM CP special messages with the
5 * "APP" prefix. Incoming messages are delivered to user space
6 * as uevents.
7 *
8 * Copyright IBM Corp. 2010
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 *
11 */
12#define KMSG_COMPONENT "smsgiucv_app"
13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14
15#include <linux/ctype.h>
16#include <linux/err.h>
17#include <linux/device.h>
18#include <linux/list.h>
19#include <linux/kobject.h>
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <linux/workqueue.h>
23#include <net/iucv/iucv.h>
24#include "smsgiucv.h"
25
26/* prefix used for SMSG registration */
27#define SMSG_PREFIX "APP"
28
29/* SMSG related uevent environment variables */
30#define ENV_SENDER_STR "SMSG_SENDER="
31#define ENV_SENDER_LEN (strlen(ENV_SENDER_STR) + 8 + 1)
32#define ENV_PREFIX_STR "SMSG_ID="
33#define ENV_PREFIX_LEN (strlen(ENV_PREFIX_STR) + \
34 strlen(SMSG_PREFIX) + 1)
35#define ENV_TEXT_STR "SMSG_TEXT="
36#define ENV_TEXT_LEN(msg) (strlen(ENV_TEXT_STR) + strlen((msg)) + 1)
37
38/* z/VM user ID which is permitted to send SMSGs
39 * If the value is undefined or empty (""), special messages are
40 * accepted from any z/VM user ID. */
41static char *sender;
42module_param(sender, charp, 0400);
43MODULE_PARM_DESC(sender, "z/VM user ID from which CP SMSGs are accepted");
44
45/* SMSG device representation */
46static struct device *smsg_app_dev;
47
48/* list element for queuing received messages for delivery */
49struct smsg_app_event {
50 struct list_head list;
51 char *buf;
52 char *envp[4];
53};
54
55/* queue for outgoing uevents */
56static LIST_HEAD(smsg_event_queue);
57static DEFINE_SPINLOCK(smsg_event_queue_lock);
58
59static void smsg_app_event_free(struct smsg_app_event *ev)
60{
61 kfree(ev->buf);
62 kfree(ev);
63}
64
65static struct smsg_app_event *smsg_app_event_alloc(const char *from,
66 const char *msg)
67{
68 struct smsg_app_event *ev;
69
70 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
71 if (!ev)
72 return NULL;
73
74 ev->buf = kzalloc(ENV_SENDER_LEN + ENV_PREFIX_LEN +
75 ENV_TEXT_LEN(msg), GFP_ATOMIC);
76 if (!ev->buf) {
77 kfree(ev);
78 return NULL;
79 }
80
81 /* setting up environment pointers into buf */
82 ev->envp[0] = ev->buf;
83 ev->envp[1] = ev->envp[0] + ENV_SENDER_LEN;
84 ev->envp[2] = ev->envp[1] + ENV_PREFIX_LEN;
85 ev->envp[3] = NULL;
86
87 /* setting up environment: sender, prefix name, and message text */
88 snprintf(ev->envp[0], ENV_SENDER_LEN, ENV_SENDER_STR "%s", from);
89 snprintf(ev->envp[1], ENV_PREFIX_LEN, ENV_PREFIX_STR "%s", SMSG_PREFIX);
90 snprintf(ev->envp[2], ENV_TEXT_LEN(msg), ENV_TEXT_STR "%s", msg);
91
92 return ev;
93}
94
95static void smsg_event_work_fn(struct work_struct *work)
96{
97 LIST_HEAD(event_queue);
98 struct smsg_app_event *p, *n;
99 struct device *dev;
100
101 dev = get_device(smsg_app_dev);
102 if (!dev)
103 return;
104
105 spin_lock_bh(&smsg_event_queue_lock);
106 list_splice_init(&smsg_event_queue, &event_queue);
107 spin_unlock_bh(&smsg_event_queue_lock);
108
109 list_for_each_entry_safe(p, n, &event_queue, list) {
110 list_del(&p->list);
111 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, p->envp);
112 smsg_app_event_free(p);
113 }
114
115 put_device(dev);
116}
117static DECLARE_WORK(smsg_event_work, smsg_event_work_fn);
118
119static void smsg_app_callback(const char *from, char *msg)
120{
121 struct smsg_app_event *se;
122
123 /* check if the originating z/VM user ID matches
124 * the configured sender. */
125 if (sender && strlen(sender) > 0 && strcmp(from, sender) != 0)
126 return;
127
128 /* get start of message text (skip prefix and leading blanks) */
129 msg += strlen(SMSG_PREFIX);
130 while (*msg && isspace(*msg))
131 msg++;
132 if (*msg == '\0')
133 return;
134
135 /* allocate event list element and its environment */
136 se = smsg_app_event_alloc(from, msg);
137 if (!se)
138 return;
139
140 /* queue event and schedule work function */
141 spin_lock(&smsg_event_queue_lock);
142 list_add_tail(&se->list, &smsg_event_queue);
143 spin_unlock(&smsg_event_queue_lock);
144
145 schedule_work(&smsg_event_work);
146 return;
147}
148
149static int __init smsgiucv_app_init(void)
150{
151 struct device_driver *smsgiucv_drv;
152 int rc;
153
154 if (!MACHINE_IS_VM)
155 return -ENODEV;
156
157 smsg_app_dev = kzalloc(sizeof(*smsg_app_dev), GFP_KERNEL);
158 if (!smsg_app_dev)
159 return -ENOMEM;
160
161 smsgiucv_drv = driver_find(SMSGIUCV_DRV_NAME, &iucv_bus);
162 if (!smsgiucv_drv) {
163 kfree(smsg_app_dev);
164 return -ENODEV;
165 }
166
167 rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
168 if (rc) {
169 kfree(smsg_app_dev);
170 goto fail_put_driver;
171 }
172 smsg_app_dev->bus = &iucv_bus;
173 smsg_app_dev->parent = iucv_root;
174 smsg_app_dev->release = (void (*)(struct device *)) kfree;
175 smsg_app_dev->driver = smsgiucv_drv;
176 rc = device_register(smsg_app_dev);
177 if (rc) {
178 put_device(smsg_app_dev);
179 goto fail_put_driver;
180 }
181
182 /* register with the smsgiucv device driver */
183 rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
184 if (rc) {
185 device_unregister(smsg_app_dev);
186 goto fail_put_driver;
187 }
188
189 rc = 0;
190fail_put_driver:
191 put_driver(smsgiucv_drv);
192 return rc;
193}
194module_init(smsgiucv_app_init);
195
196static void __exit smsgiucv_app_exit(void)
197{
198 /* unregister callback */
199 smsg_unregister_callback(SMSG_PREFIX, smsg_app_callback);
200
201 /* cancel pending work and flush any queued event work */
202 cancel_work_sync(&smsg_event_work);
203 smsg_event_work_fn(&smsg_event_work);
204
205 device_unregister(smsg_app_dev);
206}
207module_exit(smsgiucv_app_exit);
208
209MODULE_LICENSE("GPL v2");
210MODULE_DESCRIPTION("Deliver z/VM CP SMSG as uevents");
211MODULE_AUTHOR("Hendrik Brueckner <brueckner@linux.vnet.ibm.com>");
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 71b97ff77cf0..6479273a3094 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -319,8 +319,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
319 id->input_handler = zfcp_qdio_int_resp; 319 id->input_handler = zfcp_qdio_int_resp;
320 id->output_handler = zfcp_qdio_int_req; 320 id->output_handler = zfcp_qdio_int_req;
321 id->int_parm = (unsigned long) qdio; 321 id->int_parm = (unsigned long) qdio;
322 id->flags = QDIO_INBOUND_0COPY_SBALS |
323 QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
324 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal); 322 id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
325 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal); 323 id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
326 324
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3da3f48720a7..bdcdbd53da89 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -55,6 +55,11 @@ config SOFT_WATCHDOG
55 To compile this driver as a module, choose M here: the 55 To compile this driver as a module, choose M here: the
56 module will be called softdog. 56 module will be called softdog.
57 57
58config MAX63XX_WATCHDOG
59 tristate "Max63xx watchdog"
60 help
61 Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
62
58config WM831X_WATCHDOG 63config WM831X_WATCHDOG
59 tristate "WM831x watchdog" 64 tristate "WM831x watchdog"
60 depends on MFD_WM831X 65 depends on MFD_WM831X
@@ -289,6 +294,17 @@ config ADX_WATCHDOG
289 Say Y here if you want support for the watchdog timer on Avionic 294 Say Y here if you want support for the watchdog timer on Avionic
290 Design Xanthos boards. 295 Design Xanthos boards.
291 296
297config TS72XX_WATCHDOG
298 tristate "TS-72XX SBC Watchdog"
299 depends on MACH_TS72XX
300 help
301 Technologic Systems TS-7200, TS-7250 and TS-7260 boards have
302 watchdog timer implemented in a external CPLD chip. Say Y here
303 if you want to support for the watchdog timer on TS-72XX boards.
304
305 To compile this driver as a module, choose M here: the
306 module will be called ts72xx_wdt.
307
292# AVR32 Architecture 308# AVR32 Architecture
293 309
294config AT32AP700X_WDT 310config AT32AP700X_WDT
@@ -845,10 +861,10 @@ config TXX9_WDT
845# POWERPC Architecture 861# POWERPC Architecture
846 862
847config GEF_WDT 863config GEF_WDT
848 tristate "GE Fanuc Watchdog Timer" 864 tristate "GE Watchdog Timer"
849 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A 865 depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
850 ---help--- 866 ---help---
851 Watchdog timer found in a number of GE Fanuc single board computers. 867 Watchdog timer found in a number of GE single board computers.
852 868
853config MPC5200_WDT 869config MPC5200_WDT
854 bool "MPC52xx Watchdog Timer" 870 bool "MPC52xx Watchdog Timer"
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 475c61100069..5e3cb95bb0e9 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
46obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o 46obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
47obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o 47obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
48obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o 48obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o
49obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
49 50
50# AVR32 Architecture 51# AVR32 Architecture
51obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o 52obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -142,4 +143,5 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o
142# Architecture Independant 143# Architecture Independant
143obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o 144obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
144obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o 145obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
146obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
145obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o 147obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c
index 4d18c874d963..2ffce4d75443 100644
--- a/drivers/watchdog/acquirewdt.c
+++ b/drivers/watchdog/acquirewdt.c
@@ -150,7 +150,7 @@ static long acq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
150 int options, retval = -EINVAL; 150 int options, retval = -EINVAL;
151 void __user *argp = (void __user *)arg; 151 void __user *argp = (void __user *)arg;
152 int __user *p = argp; 152 int __user *p = argp;
153 static struct watchdog_info ident = { 153 static const struct watchdog_info ident = {
154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 154 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
155 .firmware_version = 1, 155 .firmware_version = 1,
156 .identity = WATCHDOG_NAME, 156 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 824d076a5cd6..4d40965d2c9f 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -137,7 +137,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
137 int new_timeout; 137 int new_timeout;
138 void __user *argp = (void __user *)arg; 138 void __user *argp = (void __user *)arg;
139 int __user *p = argp; 139 int __user *p = argp;
140 static struct watchdog_info ident = { 140 static const struct watchdog_info ident = {
141 .options = WDIOF_KEEPALIVEPING | 141 .options = WDIOF_KEEPALIVEPING |
142 WDIOF_SETTIMEOUT | 142 WDIOF_SETTIMEOUT |
143 WDIOF_MAGICCLOSE, 143 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c
index 9d7d155364f8..a5ca7a6ee133 100644
--- a/drivers/watchdog/adx_wdt.c
+++ b/drivers/watchdog/adx_wdt.c
@@ -37,7 +37,7 @@ struct adx_wdt {
37 spinlock_t lock; 37 spinlock_t lock;
38}; 38};
39 39
40static struct watchdog_info adx_wdt_info = { 40static const struct watchdog_info adx_wdt_info = {
41 .identity = "Avionic Design Xanthos Watchdog", 41 .identity = "Avionic Design Xanthos Watchdog",
42 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 42 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
43}; 43};
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 937a80fb61e1..1e9caea8ff8a 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -180,7 +180,7 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
180{ 180{
181 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
182 int __user *p = argp; 182 int __user *p = argp;
183 static struct watchdog_info ident = { 183 static const struct watchdog_info ident = {
184 .options = WDIOF_KEEPALIVEPING | 184 .options = WDIOF_KEEPALIVEPING |
185 WDIOF_SETTIMEOUT | 185 WDIOF_SETTIMEOUT |
186 WDIOF_MAGICCLOSE, 186 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index f90afdb1b255..d8d4da9a483d 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -238,7 +238,7 @@ static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
238{ 238{
239 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
240 int __user *p = argp; 240 int __user *p = argp;
241 static struct watchdog_info ident = { 241 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
244 .firmware_version = 1, 244 .firmware_version = 1,
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 2bb95cd308c1..c764c52412e4 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -219,7 +219,7 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data,
219static long ar7_wdt_ioctl(struct file *file, 219static long ar7_wdt_ioctl(struct file *file,
220 unsigned int cmd, unsigned long arg) 220 unsigned int cmd, unsigned long arg)
221{ 221{
222 static struct watchdog_info ident = { 222 static const struct watchdog_info ident = {
223 .identity = LONGNAME, 223 .identity = LONGNAME,
224 .firmware_version = 1, 224 .firmware_version = 1,
225 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 225 .options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 037847923dcb..6873376f986c 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -202,7 +202,7 @@ static int at32_wdt_get_status(void)
202 return status; 202 return status;
203} 203}
204 204
205static struct watchdog_info at32_wdt_info = { 205static const struct watchdog_info at32_wdt_info = {
206 .identity = "at32ap700x watchdog", 206 .identity = "at32ap700x watchdog",
207 .options = WDIOF_SETTIMEOUT | 207 .options = WDIOF_SETTIMEOUT |
208 WDIOF_KEEPALIVEPING | 208 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index b185dafe1494..b3046dc4b56c 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -121,7 +121,7 @@ static int at91_wdt_settimeout(int new_time)
121 return 0; 121 return 0;
122} 122}
123 123
124static struct watchdog_info at91_wdt_info = { 124static const struct watchdog_info at91_wdt_info = {
125 .identity = "at91 watchdog", 125 .identity = "at91 watchdog",
126 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 126 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
127}; 127};
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 751c003864ad..5f245522397b 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -149,7 +149,7 @@ static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data,
149 return len; 149 return len;
150} 150}
151 151
152static struct watchdog_info bcm47xx_wdt_info = { 152static const struct watchdog_info bcm47xx_wdt_info = {
153 .identity = DRV_NAME, 153 .identity = DRV_NAME,
154 .options = WDIOF_SETTIMEOUT | 154 .options = WDIOF_SETTIMEOUT |
155 WDIOF_KEEPALIVEPING | 155 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index 2159e668751c..9c7ccd1e9088 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -19,8 +19,6 @@
19#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
20#include <linux/watchdog.h> 20#include <linux/watchdog.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/notifier.h>
23#include <linux/reboot.h>
24#include <linux/init.h> 22#include <linux/init.h>
25#include <linux/interrupt.h> 23#include <linux/interrupt.h>
26#include <linux/uaccess.h> 24#include <linux/uaccess.h>
@@ -74,7 +72,7 @@
74 72
75static unsigned int timeout = WATCHDOG_TIMEOUT; 73static unsigned int timeout = WATCHDOG_TIMEOUT;
76static int nowayout = WATCHDOG_NOWAYOUT; 74static int nowayout = WATCHDOG_NOWAYOUT;
77static struct watchdog_info bfin_wdt_info; 75static const struct watchdog_info bfin_wdt_info;
78static unsigned long open_check; 76static unsigned long open_check;
79static char expect_close; 77static char expect_close;
80static DEFINE_SPINLOCK(bfin_wdt_spinlock); 78static DEFINE_SPINLOCK(bfin_wdt_spinlock);
@@ -309,26 +307,6 @@ static long bfin_wdt_ioctl(struct file *file,
309 } 307 }
310} 308}
311 309
312/**
313 * bfin_wdt_notify_sys - Notifier Handler
314 * @this: notifier block
315 * @code: notifier event
316 * @unused: unused
317 *
318 * Handles specific events, such as turning off the watchdog during a
319 * shutdown event.
320 */
321static int bfin_wdt_notify_sys(struct notifier_block *this,
322 unsigned long code, void *unused)
323{
324 stampit();
325
326 if (code == SYS_DOWN || code == SYS_HALT)
327 bfin_wdt_stop();
328
329 return NOTIFY_DONE;
330}
331
332#ifdef CONFIG_PM 310#ifdef CONFIG_PM
333static int state_before_suspend; 311static int state_before_suspend;
334 312
@@ -388,40 +366,28 @@ static struct miscdevice bfin_wdt_miscdev = {
388 .fops = &bfin_wdt_fops, 366 .fops = &bfin_wdt_fops,
389}; 367};
390 368
391static struct watchdog_info bfin_wdt_info = { 369static const struct watchdog_info bfin_wdt_info = {
392 .identity = "Blackfin Watchdog", 370 .identity = "Blackfin Watchdog",
393 .options = WDIOF_SETTIMEOUT | 371 .options = WDIOF_SETTIMEOUT |
394 WDIOF_KEEPALIVEPING | 372 WDIOF_KEEPALIVEPING |
395 WDIOF_MAGICCLOSE, 373 WDIOF_MAGICCLOSE,
396}; 374};
397 375
398static struct notifier_block bfin_wdt_notifier = {
399 .notifier_call = bfin_wdt_notify_sys,
400};
401
402/** 376/**
403 * bfin_wdt_probe - Initialize module 377 * bfin_wdt_probe - Initialize module
404 * 378 *
405 * Registers the misc device and notifier handler. Actual device 379 * Registers the misc device. Actual device
406 * initialization is handled by bfin_wdt_open(). 380 * initialization is handled by bfin_wdt_open().
407 */ 381 */
408static int __devinit bfin_wdt_probe(struct platform_device *pdev) 382static int __devinit bfin_wdt_probe(struct platform_device *pdev)
409{ 383{
410 int ret; 384 int ret;
411 385
412 ret = register_reboot_notifier(&bfin_wdt_notifier);
413 if (ret) {
414 pr_devinit(KERN_ERR PFX
415 "cannot register reboot notifier (err=%d)\n", ret);
416 return ret;
417 }
418
419 ret = misc_register(&bfin_wdt_miscdev); 386 ret = misc_register(&bfin_wdt_miscdev);
420 if (ret) { 387 if (ret) {
421 pr_devinit(KERN_ERR PFX 388 pr_devinit(KERN_ERR PFX
422 "cannot register miscdev on minor=%d (err=%d)\n", 389 "cannot register miscdev on minor=%d (err=%d)\n",
423 WATCHDOG_MINOR, ret); 390 WATCHDOG_MINOR, ret);
424 unregister_reboot_notifier(&bfin_wdt_notifier);
425 return ret; 391 return ret;
426 } 392 }
427 393
@@ -434,21 +400,33 @@ static int __devinit bfin_wdt_probe(struct platform_device *pdev)
434/** 400/**
435 * bfin_wdt_remove - Initialize module 401 * bfin_wdt_remove - Initialize module
436 * 402 *
437 * Unregisters the misc device and notifier handler. Actual device 403 * Unregisters the misc device. Actual device
438 * deinitialization is handled by bfin_wdt_close(). 404 * deinitialization is handled by bfin_wdt_close().
439 */ 405 */
440static int __devexit bfin_wdt_remove(struct platform_device *pdev) 406static int __devexit bfin_wdt_remove(struct platform_device *pdev)
441{ 407{
442 misc_deregister(&bfin_wdt_miscdev); 408 misc_deregister(&bfin_wdt_miscdev);
443 unregister_reboot_notifier(&bfin_wdt_notifier);
444 return 0; 409 return 0;
445} 410}
446 411
412/**
413 * bfin_wdt_shutdown - Soft Shutdown Handler
414 *
415 * Handles the soft shutdown event.
416 */
417static void bfin_wdt_shutdown(struct platform_device *pdev)
418{
419 stampit();
420
421 bfin_wdt_stop();
422}
423
447static struct platform_device *bfin_wdt_device; 424static struct platform_device *bfin_wdt_device;
448 425
449static struct platform_driver bfin_wdt_driver = { 426static struct platform_driver bfin_wdt_driver = {
450 .probe = bfin_wdt_probe, 427 .probe = bfin_wdt_probe,
451 .remove = __devexit_p(bfin_wdt_remove), 428 .remove = __devexit_p(bfin_wdt_remove),
429 .shutdown = bfin_wdt_shutdown,
452 .suspend = bfin_wdt_suspend, 430 .suspend = bfin_wdt_suspend,
453 .resume = bfin_wdt_resume, 431 .resume = bfin_wdt_resume,
454 .driver = { 432 .driver = {
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index e8380ef65c1c..8b724aad6825 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -121,7 +121,7 @@ static ssize_t booke_wdt_write(struct file *file, const char __user *buf,
121 return count; 121 return count;
122} 122}
123 123
124static struct watchdog_info ident = { 124static const struct watchdog_info ident = {
125 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 125 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
126 .identity = "PowerPC Book-E Watchdog", 126 .identity = "PowerPC Book-E Watchdog",
127}; 127};
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index 923cc68dba26..9291506b8b23 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -257,7 +257,7 @@ static long coh901327_ioctl(struct file *file, unsigned int cmd,
257 struct watchdog_info __user *ident; 257 struct watchdog_info __user *ident;
258 int __user *i; 258 int __user *i;
259 } uarg; 259 } uarg;
260 static struct watchdog_info ident = { 260 static const struct watchdog_info ident = {
261 .options = WDIOF_CARDRESET | 261 .options = WDIOF_CARDRESET |
262 WDIOF_SETTIMEOUT | 262 WDIOF_SETTIMEOUT |
263 WDIOF_KEEPALIVEPING, 263 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c
index 71f6d7eec9a8..edd3475f41db 100644
--- a/drivers/watchdog/cpu5wdt.c
+++ b/drivers/watchdog/cpu5wdt.c
@@ -154,7 +154,7 @@ static long cpu5wdt_ioctl(struct file *file, unsigned int cmd,
154 void __user *argp = (void __user *)arg; 154 void __user *argp = (void __user *)arg;
155 int __user *p = argp; 155 int __user *p = argp;
156 unsigned int value; 156 unsigned int value;
157 static struct watchdog_info ident = { 157 static const struct watchdog_info ident = {
158 .options = WDIOF_CARDRESET, 158 .options = WDIOF_CARDRESET,
159 .identity = "CPU5 WDT", 159 .identity = "CPU5 WDT",
160 }; 160 };
diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c
index 081f2955419e..37ea052d4dee 100644
--- a/drivers/watchdog/cpwd.c
+++ b/drivers/watchdog/cpwd.c
@@ -403,7 +403,7 @@ static int cpwd_release(struct inode *inode, struct file *file)
403 403
404static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 404static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
405{ 405{
406 static struct watchdog_info info = { 406 static const struct watchdog_info info = {
407 .options = WDIOF_SETTIMEOUT, 407 .options = WDIOF_SETTIMEOUT,
408 .firmware_version = 1, 408 .firmware_version = 1,
409 .identity = DRIVER_NAME, 409 .identity = DRIVER_NAME,
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 887136de1857..56162c87f5d8 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -142,7 +142,7 @@ davinci_wdt_write(struct file *file, const char *data, size_t len,
142 return len; 142 return len;
143} 143}
144 144
145static struct watchdog_info ident = { 145static const struct watchdog_info ident = {
146 .options = WDIOF_KEEPALIVEPING, 146 .options = WDIOF_KEEPALIVEPING,
147 .identity = "DaVinci Watchdog", 147 .identity = "DaVinci Watchdog",
148}; 148};
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index cdd55e0d09f8..88ed54e50f74 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -131,7 +131,7 @@ ep93xx_wdt_write(struct file *file, const char __user *data, size_t len,
131 return len; 131 return len;
132} 132}
133 133
134static struct watchdog_info ident = { 134static const struct watchdog_info ident = {
135 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE, 135 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
136 .identity = "EP93xx Watchdog", 136 .identity = "EP93xx Watchdog",
137}; 137};
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 9add3541fb42..d1c4e55b1db0 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -238,7 +238,7 @@ static long eurwdt_ioctl(struct file *file,
238{ 238{
239 void __user *argp = (void __user *)arg; 239 void __user *argp = (void __user *)arg;
240 int __user *p = argp; 240 int __user *p = argp;
241 static struct watchdog_info ident = { 241 static const struct watchdog_info ident = {
242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 242 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
243 | WDIOF_MAGICCLOSE, 243 | WDIOF_MAGICCLOSE,
244 .firmware_version = 1, 244 .firmware_version = 1,
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 734d9806a872..abdbad034a6c 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * GE Fanuc watchdog userspace interface 2 * GE watchdog userspace interface
3 * 3 *
4 * Author: Martyn Welch <martyn.welch@gefanuc.com> 4 * Author: Martyn Welch <martyn.welch@ge.com>
5 * 5 *
6 * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. 6 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
@@ -161,11 +161,11 @@ static long gef_wdt_ioctl(struct file *file, unsigned int cmd,
161 int timeout; 161 int timeout;
162 int options; 162 int options;
163 void __user *argp = (void __user *)arg; 163 void __user *argp = (void __user *)arg;
164 static struct watchdog_info info = { 164 static const struct watchdog_info info = {
165 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | 165 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
166 WDIOF_KEEPALIVEPING, 166 WDIOF_KEEPALIVEPING,
167 .firmware_version = 0, 167 .firmware_version = 0,
168 .identity = "GE Fanuc watchdog", 168 .identity = "GE watchdog",
169 }; 169 };
170 170
171 switch (cmd) { 171 switch (cmd) {
@@ -311,7 +311,7 @@ static struct of_platform_driver gef_wdt_driver = {
311 311
312static int __init gef_wdt_init(void) 312static int __init gef_wdt_init(void)
313{ 313{
314 printk(KERN_INFO "GE Fanuc watchdog driver\n"); 314 printk(KERN_INFO "GE watchdog driver\n");
315 return of_register_platform_driver(&gef_wdt_driver); 315 return of_register_platform_driver(&gef_wdt_driver);
316} 316}
317 317
@@ -323,8 +323,8 @@ static void __exit gef_wdt_exit(void)
323module_init(gef_wdt_init); 323module_init(gef_wdt_init);
324module_exit(gef_wdt_exit); 324module_exit(gef_wdt_exit);
325 325
326MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); 326MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
327MODULE_DESCRIPTION("GE Fanuc watchdog driver"); 327MODULE_DESCRIPTION("GE watchdog driver");
328MODULE_LICENSE("GPL"); 328MODULE_LICENSE("GPL");
329MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 329MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
330MODULE_ALIAS("platform: gef_wdt"); 330MODULE_ALIAS("platform: gef_wdt");
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c
index 38252ff828ca..9b49b125ad5a 100644
--- a/drivers/watchdog/geodewdt.c
+++ b/drivers/watchdog/geodewdt.c
@@ -142,7 +142,7 @@ static long geodewdt_ioctl(struct file *file, unsigned int cmd,
142 int __user *p = argp; 142 int __user *p = argp;
143 int interval; 143 int interval;
144 144
145 static struct watchdog_info ident = { 145 static const struct watchdog_info ident = {
146 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING 146 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING
147 | WDIOF_MAGICCLOSE, 147 | WDIOF_MAGICCLOSE,
148 .firmware_version = 1, 148 .firmware_version = 1,
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index a6c5674c78e6..70c2c24660d0 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -554,7 +554,7 @@ static ssize_t hpwdt_write(struct file *file, const char __user *data,
554 return len; 554 return len;
555} 555}
556 556
557static struct watchdog_info ident = { 557static const struct watchdog_info ident = {
558 .options = WDIOF_SETTIMEOUT | 558 .options = WDIOF_SETTIMEOUT |
559 WDIOF_KEEPALIVEPING | 559 WDIOF_KEEPALIVEPING |
560 WDIOF_MAGICCLOSE, 560 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index 7ba0b11ec525..bb9750a03942 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -34,7 +34,6 @@
34#include <linux/mm.h> 34#include <linux/mm.h>
35#include <linux/miscdevice.h> 35#include <linux/miscdevice.h>
36#include <linux/watchdog.h> 36#include <linux/watchdog.h>
37#include <linux/platform_device.h>
38#include <linux/init.h> 37#include <linux/init.h>
39#include <linux/pci.h> 38#include <linux/pci.h>
40#include <linux/ioport.h> 39#include <linux/ioport.h>
@@ -42,7 +41,7 @@
42#include <linux/io.h> 41#include <linux/io.h>
43 42
44/* Module and version information */ 43/* Module and version information */
45#define ESB_VERSION "0.04" 44#define ESB_VERSION "0.05"
46#define ESB_MODULE_NAME "i6300ESB timer" 45#define ESB_MODULE_NAME "i6300ESB timer"
47#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION 46#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
48#define PFX ESB_MODULE_NAME ": " 47#define PFX ESB_MODULE_NAME ": "
@@ -65,7 +64,7 @@
65/* Config register bits */ 64/* Config register bits */
66#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */ 65#define ESB_WDT_REBOOT (0x01 << 5) /* Enable reboot on timeout */
67#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */ 66#define ESB_WDT_FREQ (0x01 << 2) /* Decrement frequency */
68#define ESB_WDT_INTTYPE (0x11 << 0) /* Interrupt type on timer1 timeout */ 67#define ESB_WDT_INTTYPE (0x03 << 0) /* Interrupt type on timer1 timeout */
69 68
70/* Reload register bits */ 69/* Reload register bits */
71#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */ 70#define ESB_WDT_TIMEOUT (0x01 << 9) /* Watchdog timed out */
@@ -82,7 +81,9 @@ static unsigned long timer_alive;
82static struct pci_dev *esb_pci; 81static struct pci_dev *esb_pci;
83static unsigned short triggered; /* The status of the watchdog upon boot */ 82static unsigned short triggered; /* The status of the watchdog upon boot */
84static char esb_expect_close; 83static char esb_expect_close;
85static struct platform_device *esb_platform_device; 84
85/* We can only use 1 card due to the /dev/watchdog restriction */
86static int cards_found;
86 87
87/* module parameters */ 88/* module parameters */
88/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */ 89/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
@@ -111,8 +112,8 @@ MODULE_PARM_DESC(nowayout,
111 */ 112 */
112static inline void esb_unlock_registers(void) 113static inline void esb_unlock_registers(void)
113{ 114{
114 writeb(ESB_UNLOCK1, ESB_RELOAD_REG); 115 writew(ESB_UNLOCK1, ESB_RELOAD_REG);
115 writeb(ESB_UNLOCK2, ESB_RELOAD_REG); 116 writew(ESB_UNLOCK2, ESB_RELOAD_REG);
116} 117}
117 118
118static int esb_timer_start(void) 119static int esb_timer_start(void)
@@ -256,7 +257,7 @@ static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
256 int new_heartbeat; 257 int new_heartbeat;
257 void __user *argp = (void __user *)arg; 258 void __user *argp = (void __user *)arg;
258 int __user *p = argp; 259 int __user *p = argp;
259 static struct watchdog_info ident = { 260 static const struct watchdog_info ident = {
260 .options = WDIOF_SETTIMEOUT | 261 .options = WDIOF_SETTIMEOUT |
261 WDIOF_KEEPALIVEPING | 262 WDIOF_KEEPALIVEPING |
262 WDIOF_MAGICCLOSE, 263 WDIOF_MAGICCLOSE,
@@ -332,11 +333,6 @@ static struct miscdevice esb_miscdev = {
332 333
333/* 334/*
334 * Data for PCI driver interface 335 * Data for PCI driver interface
335 *
336 * This data only exists for exporting the supported
337 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
338 * register a pci_driver, because someone else might one day
339 * want to register another driver on the same PCI id.
340 */ 336 */
341static struct pci_device_id esb_pci_tbl[] = { 337static struct pci_device_id esb_pci_tbl[] = {
342 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), }, 338 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
@@ -348,29 +344,19 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
348 * Init & exit routines 344 * Init & exit routines
349 */ 345 */
350 346
351static unsigned char __devinit esb_getdevice(void) 347static unsigned char __devinit esb_getdevice(struct pci_dev *pdev)
352{ 348{
353 /* 349 if (pci_enable_device(pdev)) {
354 * Find the PCI device
355 */
356
357 esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
358 PCI_DEVICE_ID_INTEL_ESB_9, NULL);
359
360 if (!esb_pci)
361 return 0;
362
363 if (pci_enable_device(esb_pci)) {
364 printk(KERN_ERR PFX "failed to enable device\n"); 350 printk(KERN_ERR PFX "failed to enable device\n");
365 goto err_devput; 351 goto err_devput;
366 } 352 }
367 353
368 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) { 354 if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
369 printk(KERN_ERR PFX "failed to request region\n"); 355 printk(KERN_ERR PFX "failed to request region\n");
370 goto err_disable; 356 goto err_disable;
371 } 357 }
372 358
373 BASEADDR = pci_ioremap_bar(esb_pci, 0); 359 BASEADDR = pci_ioremap_bar(pdev, 0);
374 if (BASEADDR == NULL) { 360 if (BASEADDR == NULL) {
375 /* Something's wrong here, BASEADDR has to be set */ 361 /* Something's wrong here, BASEADDR has to be set */
376 printk(KERN_ERR PFX "failed to get BASEADDR\n"); 362 printk(KERN_ERR PFX "failed to get BASEADDR\n");
@@ -378,14 +364,14 @@ static unsigned char __devinit esb_getdevice(void)
378 } 364 }
379 365
380 /* Done */ 366 /* Done */
367 esb_pci = pdev;
381 return 1; 368 return 1;
382 369
383err_release: 370err_release:
384 pci_release_region(esb_pci, 0); 371 pci_release_region(pdev, 0);
385err_disable: 372err_disable:
386 pci_disable_device(esb_pci); 373 pci_disable_device(pdev);
387err_devput: 374err_devput:
388 pci_dev_put(esb_pci);
389 return 0; 375 return 0;
390} 376}
391 377
@@ -430,12 +416,23 @@ static void __devinit esb_initdevice(void)
430 esb_timer_set_heartbeat(heartbeat); 416 esb_timer_set_heartbeat(heartbeat);
431} 417}
432 418
433static int __devinit esb_probe(struct platform_device *dev) 419static int __devinit esb_probe(struct pci_dev *pdev,
420 const struct pci_device_id *ent)
434{ 421{
435 int ret; 422 int ret;
436 423
424 cards_found++;
425 if (cards_found == 1)
426 printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
427 ESB_VERSION);
428
429 if (cards_found > 1) {
430 printk(KERN_ERR PFX "This driver only supports 1 device\n");
431 return -ENODEV;
432 }
433
437 /* Check whether or not the hardware watchdog is there */ 434 /* Check whether or not the hardware watchdog is there */
438 if (!esb_getdevice() || esb_pci == NULL) 435 if (!esb_getdevice(pdev) || esb_pci == NULL)
439 return -ENODEV; 436 return -ENODEV;
440 437
441 /* Check that the heartbeat value is within it's range; 438 /* Check that the heartbeat value is within it's range;
@@ -467,11 +464,11 @@ err_unmap:
467 iounmap(BASEADDR); 464 iounmap(BASEADDR);
468 pci_release_region(esb_pci, 0); 465 pci_release_region(esb_pci, 0);
469 pci_disable_device(esb_pci); 466 pci_disable_device(esb_pci);
470 pci_dev_put(esb_pci); 467 esb_pci = NULL;
471 return ret; 468 return ret;
472} 469}
473 470
474static int __devexit esb_remove(struct platform_device *dev) 471static void __devexit esb_remove(struct pci_dev *pdev)
475{ 472{
476 /* Stop the timer before we leave */ 473 /* Stop the timer before we leave */
477 if (!nowayout) 474 if (!nowayout)
@@ -482,54 +479,30 @@ static int __devexit esb_remove(struct platform_device *dev)
482 iounmap(BASEADDR); 479 iounmap(BASEADDR);
483 pci_release_region(esb_pci, 0); 480 pci_release_region(esb_pci, 0);
484 pci_disable_device(esb_pci); 481 pci_disable_device(esb_pci);
485 pci_dev_put(esb_pci); 482 esb_pci = NULL;
486 return 0;
487} 483}
488 484
489static void esb_shutdown(struct platform_device *dev) 485static void esb_shutdown(struct pci_dev *pdev)
490{ 486{
491 esb_timer_stop(); 487 esb_timer_stop();
492} 488}
493 489
494static struct platform_driver esb_platform_driver = { 490static struct pci_driver esb_driver = {
491 .name = ESB_MODULE_NAME,
492 .id_table = esb_pci_tbl,
495 .probe = esb_probe, 493 .probe = esb_probe,
496 .remove = __devexit_p(esb_remove), 494 .remove = __devexit_p(esb_remove),
497 .shutdown = esb_shutdown, 495 .shutdown = esb_shutdown,
498 .driver = {
499 .owner = THIS_MODULE,
500 .name = ESB_MODULE_NAME,
501 },
502}; 496};
503 497
504static int __init watchdog_init(void) 498static int __init watchdog_init(void)
505{ 499{
506 int err; 500 return pci_register_driver(&esb_driver);
507
508 printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
509 ESB_VERSION);
510
511 err = platform_driver_register(&esb_platform_driver);
512 if (err)
513 return err;
514
515 esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
516 -1, NULL, 0);
517 if (IS_ERR(esb_platform_device)) {
518 err = PTR_ERR(esb_platform_device);
519 goto unreg_platform_driver;
520 }
521
522 return 0;
523
524unreg_platform_driver:
525 platform_driver_unregister(&esb_platform_driver);
526 return err;
527} 501}
528 502
529static void __exit watchdog_cleanup(void) 503static void __exit watchdog_cleanup(void)
530{ 504{
531 platform_device_unregister(esb_platform_device); 505 pci_unregister_driver(&esb_driver);
532 platform_driver_unregister(&esb_platform_driver);
533 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n"); 506 printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
534} 507}
535 508
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index 4bdb7f1a9077..44bc6aa46edf 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -584,7 +584,7 @@ static long iTCO_wdt_ioctl(struct file *file, unsigned int cmd,
584 int new_heartbeat; 584 int new_heartbeat;
585 void __user *argp = (void __user *)arg; 585 void __user *argp = (void __user *)arg;
586 int __user *p = argp; 586 int __user *p = argp;
587 static struct watchdog_info ident = { 587 static const struct watchdog_info ident = {
588 .options = WDIOF_SETTIMEOUT | 588 .options = WDIOF_SETTIMEOUT |
589 WDIOF_KEEPALIVEPING | 589 WDIOF_KEEPALIVEPING |
590 WDIOF_MAGICCLOSE, 590 WDIOF_MAGICCLOSE,
@@ -698,7 +698,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
698 if (iTCO_wdt_private.iTCO_version == 2) { 698 if (iTCO_wdt_private.iTCO_version == 2) {
699 pci_read_config_dword(pdev, 0xf0, &base_address); 699 pci_read_config_dword(pdev, 0xf0, &base_address);
700 if ((base_address & 1) == 0) { 700 if ((base_address & 1) == 0) {
701 printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); 701 printk(KERN_ERR PFX "RCBA is disabled by hardware\n");
702 ret = -ENODEV; 702 ret = -ENODEV;
703 goto out; 703 goto out;
704 } 704 }
@@ -708,8 +708,8 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
708 708
709 /* Check chipset's NO_REBOOT bit */ 709 /* Check chipset's NO_REBOOT bit */
710 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { 710 if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) {
711 printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " 711 printk(KERN_INFO PFX "unable to reset NO_REBOOT flag, "
712 "reboot disabled by hardware\n"); 712 "platform may have disabled it\n");
713 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ 713 ret = -ENODEV; /* Cannot reset NO_REBOOT bit */
714 goto out_unmap; 714 goto out_unmap;
715 } 715 }
@@ -805,6 +805,7 @@ static void __devexit iTCO_wdt_cleanup(void)
805 805
806static int __devinit iTCO_wdt_probe(struct platform_device *dev) 806static int __devinit iTCO_wdt_probe(struct platform_device *dev)
807{ 807{
808 int ret = -ENODEV;
808 int found = 0; 809 int found = 0;
809 struct pci_dev *pdev = NULL; 810 struct pci_dev *pdev = NULL;
810 const struct pci_device_id *ent; 811 const struct pci_device_id *ent;
@@ -814,19 +815,17 @@ static int __devinit iTCO_wdt_probe(struct platform_device *dev)
814 for_each_pci_dev(pdev) { 815 for_each_pci_dev(pdev) {
815 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); 816 ent = pci_match_id(iTCO_wdt_pci_tbl, pdev);
816 if (ent) { 817 if (ent) {
817 if (!(iTCO_wdt_init(pdev, ent, dev))) { 818 found++;
818 found++; 819 ret = iTCO_wdt_init(pdev, ent, dev);
820 if (!ret)
819 break; 821 break;
820 }
821 } 822 }
822 } 823 }
823 824
824 if (!found) { 825 if (!found)
825 printk(KERN_INFO PFX "No card detected\n"); 826 printk(KERN_INFO PFX "No card detected\n");
826 return -ENODEV;
827 }
828 827
829 return 0; 828 return ret;
830} 829}
831 830
832static int __devexit iTCO_wdt_remove(struct platform_device *dev) 831static int __devexit iTCO_wdt_remove(struct platform_device *dev)
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 4bef3ddff4a5..0149d8dfc81d 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -174,7 +174,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
174 void __user *argp = (void __user *)arg; 174 void __user *argp = (void __user *)arg;
175 int __user *p = argp; 175 int __user *p = argp;
176 176
177 static struct watchdog_info ident = { 177 static const struct watchdog_info ident = {
178 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT 178 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT
179 | WDIOF_MAGICCLOSE, 179 | WDIOF_MAGICCLOSE,
180 .firmware_version = 1, 180 .firmware_version = 1,
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c
index bea8a124a559..1cc5609666d1 100644
--- a/drivers/watchdog/indydog.c
+++ b/drivers/watchdog/indydog.c
@@ -111,7 +111,7 @@ static long indydog_ioctl(struct file *file, unsigned int cmd,
111 unsigned long arg) 111 unsigned long arg)
112{ 112{
113 int options, retval = -EINVAL; 113 int options, retval = -EINVAL;
114 static struct watchdog_info ident = { 114 static const struct watchdog_info ident = {
115 .options = WDIOF_KEEPALIVEPING, 115 .options = WDIOF_KEEPALIVEPING,
116 .firmware_version = 0, 116 .firmware_version = 0,
117 .identity = "Hardware Watchdog for SGI IP22", 117 .identity = "Hardware Watchdog for SGI IP22",
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c
index daed48ded7fe..f52c162b1bea 100644
--- a/drivers/watchdog/it8712f_wdt.c
+++ b/drivers/watchdog/it8712f_wdt.c
@@ -236,7 +236,7 @@ static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd,
236{ 236{
237 void __user *argp = (void __user *)arg; 237 void __user *argp = (void __user *)arg;
238 int __user *p = argp; 238 int __user *p = argp;
239 static struct watchdog_info ident = { 239 static const struct watchdog_info ident = {
240 .identity = "IT8712F Watchdog", 240 .identity = "IT8712F Watchdog",
241 .firmware_version = 1, 241 .firmware_version = 1,
242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | 242 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index cc133c531d08..b709b3b2d1ef 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -421,7 +421,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
421 return count; 421 return count;
422} 422}
423 423
424static struct watchdog_info ident = { 424static const struct watchdog_info ident = {
425 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 425 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
426 .firmware_version = 1, 426 .firmware_version = 1,
427 .identity = WATCHDOG_NAME, 427 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
index 3c79dc587958..e86952a7168c 100644
--- a/drivers/watchdog/ixp2000_wdt.c
+++ b/drivers/watchdog/ixp2000_wdt.c
@@ -100,7 +100,7 @@ static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
100} 100}
101 101
102 102
103static struct watchdog_info ident = { 103static const struct watchdog_info ident = {
104 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 104 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
105 WDIOF_KEEPALIVEPING, 105 WDIOF_KEEPALIVEPING,
106 .identity = "IXP2000 Watchdog", 106 .identity = "IXP2000 Watchdog",
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index 147b4d5c63b3..e02c0ecda26b 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -89,7 +89,7 @@ ixp4xx_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
89 return len; 89 return len;
90} 90}
91 91
92static struct watchdog_info ident = { 92static const struct watchdog_info ident = {
93 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | 93 .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
94 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 94 WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
95 .identity = "IXP4xx Watchdog", 95 .identity = "IXP4xx Watchdog",
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index e1c82769b08e..2852bb2e3fd9 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -145,7 +145,7 @@ static int ks8695_wdt_close(struct inode *inode, struct file *file)
145 return 0; 145 return 0;
146} 146}
147 147
148static struct watchdog_info ks8695_wdt_info = { 148static const struct watchdog_info ks8695_wdt_info = {
149 .identity = "ks8695 watchdog", 149 .identity = "ks8695 watchdog",
150 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 150 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
151}; 151};
diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c
index 47d719717a3b..2d118cf022fc 100644
--- a/drivers/watchdog/machzwd.c
+++ b/drivers/watchdog/machzwd.c
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(nowayout,
101 101
102#define PFX "machzwd" 102#define PFX "machzwd"
103 103
104static struct watchdog_info zf_info = { 104static const struct watchdog_info zf_info = {
105 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 105 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
106 .firmware_version = 1, 106 .firmware_version = 1,
107 .identity = "ZF-Logic watchdog", 107 .identity = "ZF-Logic watchdog",
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
new file mode 100644
index 000000000000..6eb91d757604
--- /dev/null
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -0,0 +1,397 @@
1/*
2 * drivers/char/watchdog/max63xx_wdt.c
3 *
4 * Driver for max63{69,70,71,72,73,74} watchdog timers
5 *
6 * Copyright (C) 2009 Marc Zyngier <maz@misterjones.org>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 *
12 * This driver assumes the watchdog pins are memory mapped (as it is
13 * the case for the Arcom Zeus). Should it be connected over GPIOs or
14 * another interface, some abstraction will have to be introduced.
15 */
16
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/fs.h>
22#include <linux/miscdevice.h>
23#include <linux/watchdog.h>
24#include <linux/init.h>
25#include <linux/bitops.h>
26#include <linux/platform_device.h>
27#include <linux/spinlock.h>
28#include <linux/uaccess.h>
29#include <linux/io.h>
30#include <linux/device.h>
31
32#define DEFAULT_HEARTBEAT 60
33#define MAX_HEARTBEAT 60
34
35static int heartbeat = DEFAULT_HEARTBEAT;
36static int nowayout = WATCHDOG_NOWAYOUT;
37
38/*
39 * Memory mapping: a single byte, 3 first lower bits to select bit 3
40 * to ping the watchdog.
41 */
42#define MAX6369_WDSET (7 << 0)
43#define MAX6369_WDI (1 << 3)
44
45static DEFINE_SPINLOCK(io_lock);
46
47static unsigned long wdt_status;
48#define WDT_IN_USE 0
49#define WDT_RUNNING 1
50#define WDT_OK_TO_CLOSE 2
51
52static int nodelay;
53static struct resource *wdt_mem;
54static void __iomem *wdt_base;
55static struct platform_device *max63xx_pdev;
56
57/*
58 * The timeout values used are actually the absolute minimum the chip
59 * offers. Typical values on my board are slightly over twice as long
60 * (10s setting ends up with a 25s timeout), and can be up to 3 times
61 * the nominal setting (according to the datasheet). So please take
62 * these values with a grain of salt. Same goes for the initial delay
63 * "feature". Only max6373/74 have a few settings without this initial
64 * delay (selected with the "nodelay" parameter).
65 *
66 * I also decided to remove from the tables any timeout smaller than a
67 * second, as it looked completly overkill...
68 */
69
70/* Timeouts in second */
71struct max63xx_timeout {
72 u8 wdset;
73 u8 tdelay;
74 u8 twd;
75};
76
77static struct max63xx_timeout max6369_table[] = {
78 { 5, 1, 1 },
79 { 6, 10, 10 },
80 { 7, 60, 60 },
81 { },
82};
83
84static struct max63xx_timeout max6371_table[] = {
85 { 6, 60, 3 },
86 { 7, 60, 60 },
87 { },
88};
89
90static struct max63xx_timeout max6373_table[] = {
91 { 2, 60, 1 },
92 { 5, 0, 1 },
93 { 1, 3, 3 },
94 { 7, 60, 10 },
95 { 6, 0, 10 },
96 { },
97};
98
99static struct max63xx_timeout *current_timeout;
100
101static struct max63xx_timeout *
102max63xx_select_timeout(struct max63xx_timeout *table, int value)
103{
104 while (table->twd) {
105 if (value <= table->twd) {
106 if (nodelay && table->tdelay == 0)
107 return table;
108
109 if (!nodelay)
110 return table;
111 }
112
113 table++;
114 }
115
116 return NULL;
117}
118
119static void max63xx_wdt_ping(void)
120{
121 u8 val;
122
123 spin_lock(&io_lock);
124
125 val = __raw_readb(wdt_base);
126
127 __raw_writeb(val | MAX6369_WDI, wdt_base);
128 __raw_writeb(val & ~MAX6369_WDI, wdt_base);
129
130 spin_unlock(&io_lock);
131}
132
133static void max63xx_wdt_enable(struct max63xx_timeout *entry)
134{
135 u8 val;
136
137 if (test_and_set_bit(WDT_RUNNING, &wdt_status))
138 return;
139
140 spin_lock(&io_lock);
141
142 val = __raw_readb(wdt_base);
143 val &= ~MAX6369_WDSET;
144 val |= entry->wdset;
145 __raw_writeb(val, wdt_base);
146
147 spin_unlock(&io_lock);
148
149 /* check for a edge triggered startup */
150 if (entry->tdelay == 0)
151 max63xx_wdt_ping();
152}
153
154static void max63xx_wdt_disable(void)
155{
156 spin_lock(&io_lock);
157
158 __raw_writeb(3, wdt_base);
159
160 spin_unlock(&io_lock);
161
162 clear_bit(WDT_RUNNING, &wdt_status);
163}
164
165static int max63xx_wdt_open(struct inode *inode, struct file *file)
166{
167 if (test_and_set_bit(WDT_IN_USE, &wdt_status))
168 return -EBUSY;
169
170 max63xx_wdt_enable(current_timeout);
171 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
172
173 return nonseekable_open(inode, file);
174}
175
176static ssize_t max63xx_wdt_write(struct file *file, const char *data,
177 size_t len, loff_t *ppos)
178{
179 if (len) {
180 if (!nowayout) {
181 size_t i;
182
183 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
184 for (i = 0; i != len; i++) {
185 char c;
186
187 if (get_user(c, data + i))
188 return -EFAULT;
189
190 if (c == 'V')
191 set_bit(WDT_OK_TO_CLOSE, &wdt_status);
192 }
193 }
194
195 max63xx_wdt_ping();
196 }
197
198 return len;
199}
200
201static const struct watchdog_info ident = {
202 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
203 .identity = "max63xx Watchdog",
204};
205
206static long max63xx_wdt_ioctl(struct file *file, unsigned int cmd,
207 unsigned long arg)
208{
209 int ret = -ENOTTY;
210
211 switch (cmd) {
212 case WDIOC_GETSUPPORT:
213 ret = copy_to_user((struct watchdog_info *)arg, &ident,
214 sizeof(ident)) ? -EFAULT : 0;
215 break;
216
217 case WDIOC_GETSTATUS:
218 case WDIOC_GETBOOTSTATUS:
219 ret = put_user(0, (int *)arg);
220 break;
221
222 case WDIOC_KEEPALIVE:
223 max63xx_wdt_ping();
224 ret = 0;
225 break;
226
227 case WDIOC_GETTIMEOUT:
228 ret = put_user(heartbeat, (int *)arg);
229 break;
230 }
231 return ret;
232}
233
234static int max63xx_wdt_release(struct inode *inode, struct file *file)
235{
236 if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
237 max63xx_wdt_disable();
238 else
239 dev_crit(&max63xx_pdev->dev,
240 "device closed unexpectedly - timer will not stop\n");
241
242 clear_bit(WDT_IN_USE, &wdt_status);
243 clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
244
245 return 0;
246}
247
248static const struct file_operations max63xx_wdt_fops = {
249 .owner = THIS_MODULE,
250 .llseek = no_llseek,
251 .write = max63xx_wdt_write,
252 .unlocked_ioctl = max63xx_wdt_ioctl,
253 .open = max63xx_wdt_open,
254 .release = max63xx_wdt_release,
255};
256
257static struct miscdevice max63xx_wdt_miscdev = {
258 .minor = WATCHDOG_MINOR,
259 .name = "watchdog",
260 .fops = &max63xx_wdt_fops,
261};
262
263static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
264{
265 int ret = 0;
266 int size;
267 struct resource *res;
268 struct device *dev = &pdev->dev;
269 struct max63xx_timeout *table;
270
271 table = (struct max63xx_timeout *)pdev->id_entry->driver_data;
272
273 if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
274 heartbeat = DEFAULT_HEARTBEAT;
275
276 dev_info(dev, "requesting %ds heartbeat\n", heartbeat);
277 current_timeout = max63xx_select_timeout(table, heartbeat);
278
279 if (!current_timeout) {
280 dev_err(dev, "unable to satisfy heartbeat request\n");
281 return -EINVAL;
282 }
283
284 dev_info(dev, "using %ds heartbeat with %ds initial delay\n",
285 current_timeout->twd, current_timeout->tdelay);
286
287 heartbeat = current_timeout->twd;
288
289 max63xx_pdev = pdev;
290
291 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292 if (res == NULL) {
293 dev_err(dev, "failed to get memory region resource\n");
294 return -ENOENT;
295 }
296
297 size = resource_size(res);
298 wdt_mem = request_mem_region(res->start, size, pdev->name);
299
300 if (wdt_mem == NULL) {
301 dev_err(dev, "failed to get memory region\n");
302 return -ENOENT;
303 }
304
305 wdt_base = ioremap(res->start, size);
306 if (!wdt_base) {
307 dev_err(dev, "failed to map memory region\n");
308 ret = -ENOMEM;
309 goto out_request;
310 }
311
312 ret = misc_register(&max63xx_wdt_miscdev);
313 if (ret < 0) {
314 dev_err(dev, "cannot register misc device\n");
315 goto out_unmap;
316 }
317
318 return 0;
319
320out_unmap:
321 iounmap(wdt_base);
322out_request:
323 release_resource(wdt_mem);
324 kfree(wdt_mem);
325
326 return ret;
327}
328
329static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
330{
331 misc_deregister(&max63xx_wdt_miscdev);
332 if (wdt_mem) {
333 release_resource(wdt_mem);
334 kfree(wdt_mem);
335 wdt_mem = NULL;
336 }
337
338 if (wdt_base)
339 iounmap(wdt_base);
340
341 return 0;
342}
343
344static struct platform_device_id max63xx_id_table[] = {
345 { "max6369_wdt", (kernel_ulong_t)max6369_table, },
346 { "max6370_wdt", (kernel_ulong_t)max6369_table, },
347 { "max6371_wdt", (kernel_ulong_t)max6371_table, },
348 { "max6372_wdt", (kernel_ulong_t)max6371_table, },
349 { "max6373_wdt", (kernel_ulong_t)max6373_table, },
350 { "max6374_wdt", (kernel_ulong_t)max6373_table, },
351 { },
352};
353MODULE_DEVICE_TABLE(platform, max63xx_id_table);
354
355static struct platform_driver max63xx_wdt_driver = {
356 .probe = max63xx_wdt_probe,
357 .remove = __devexit_p(max63xx_wdt_remove),
358 .id_table = max63xx_id_table,
359 .driver = {
360 .name = "max63xx_wdt",
361 .owner = THIS_MODULE,
362 },
363};
364
365static int __init max63xx_wdt_init(void)
366{
367 return platform_driver_register(&max63xx_wdt_driver);
368}
369
370static void __exit max63xx_wdt_exit(void)
371{
372 platform_driver_unregister(&max63xx_wdt_driver);
373}
374
375module_init(max63xx_wdt_init);
376module_exit(max63xx_wdt_exit);
377
378MODULE_AUTHOR("Marc Zyngier <maz@misterjones.org>");
379MODULE_DESCRIPTION("max63xx Watchdog Driver");
380
381module_param(heartbeat, int, 0);
382MODULE_PARM_DESC(heartbeat,
383 "Watchdog heartbeat period in seconds from 1 to "
384 __MODULE_STRING(MAX_HEARTBEAT) ", default "
385 __MODULE_STRING(DEFAULT_HEARTBEAT));
386
387module_param(nowayout, int, 0);
388MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
389 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
390
391module_param(nodelay, int, 0);
392MODULE_PARM_DESC(nodelay,
393 "Force selection of a timeout setting without initial delay "
394 "(max6373/74 only, default=0)");
395
396MODULE_LICENSE("GPL");
397MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c
index 407b025cb104..bc820d16699a 100644
--- a/drivers/watchdog/mixcomwd.c
+++ b/drivers/watchdog/mixcomwd.c
@@ -201,7 +201,7 @@ static long mixcomwd_ioctl(struct file *file,
201 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
202 int __user *p = argp; 202 int __user *p = argp;
203 int status; 203 int status;
204 static struct watchdog_info ident = { 204 static const struct watchdog_info ident = {
205 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 205 .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
206 .firmware_version = 1, 206 .firmware_version = 1,
207 .identity = "MixCOM watchdog", 207 .identity = "MixCOM watchdog",
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 38c588ee694f..4e3941c5e293 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -148,7 +148,7 @@ static long mpc8xxx_wdt_ioctl(struct file *file, unsigned int cmd,
148{ 148{
149 void __user *argp = (void __user *)arg; 149 void __user *argp = (void __user *)arg;
150 int __user *p = argp; 150 int __user *p = argp;
151 static struct watchdog_info ident = { 151 static const struct watchdog_info ident = {
152 .options = WDIOF_KEEPALIVEPING, 152 .options = WDIOF_KEEPALIVEPING,
153 .firmware_version = 1, 153 .firmware_version = 1,
154 .identity = "MPC8xxx", 154 .identity = "MPC8xxx",
diff --git a/drivers/watchdog/mpcore_wdt.c b/drivers/watchdog/mpcore_wdt.c
index a2dc07c2ed49..b0646dac924e 100644
--- a/drivers/watchdog/mpcore_wdt.c
+++ b/drivers/watchdog/mpcore_wdt.c
@@ -213,7 +213,7 @@ static ssize_t mpcore_wdt_write(struct file *file, const char *data,
213 return len; 213 return len;
214} 214}
215 215
216static struct watchdog_info ident = { 216static const struct watchdog_info ident = {
217 .options = WDIOF_SETTIMEOUT | 217 .options = WDIOF_SETTIMEOUT |
218 WDIOF_KEEPALIVEPING | 218 WDIOF_KEEPALIVEPING |
219 WDIOF_MAGICCLOSE, 219 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/mv64x60_wdt.c b/drivers/watchdog/mv64x60_wdt.c
index a51dbe4c43da..97f8a48d8b78 100644
--- a/drivers/watchdog/mv64x60_wdt.c
+++ b/drivers/watchdog/mv64x60_wdt.c
@@ -179,7 +179,7 @@ static long mv64x60_wdt_ioctl(struct file *file,
179 int timeout; 179 int timeout;
180 int options; 180 int options;
181 void __user *argp = (void __user *)arg; 181 void __user *argp = (void __user *)arg;
182 static struct watchdog_info info = { 182 static const struct watchdog_info info = {
183 .options = WDIOF_SETTIMEOUT | 183 .options = WDIOF_SETTIMEOUT |
184 WDIOF_MAGICCLOSE | 184 WDIOF_MAGICCLOSE |
185 WDIOF_KEEPALIVEPING, 185 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c
index 1a2b916e3f8d..d3aa2f1fe61d 100644
--- a/drivers/watchdog/pc87413_wdt.c
+++ b/drivers/watchdog/pc87413_wdt.c
@@ -407,7 +407,7 @@ static long pc87413_ioctl(struct file *file, unsigned int cmd,
407 int __user *i; 407 int __user *i;
408 } uarg; 408 } uarg;
409 409
410 static struct watchdog_info ident = { 410 static const struct watchdog_info ident = {
411 .options = WDIOF_KEEPALIVEPING | 411 .options = WDIOF_KEEPALIVEPING |
412 WDIOF_SETTIMEOUT | 412 WDIOF_SETTIMEOUT |
413 WDIOF_MAGICCLOSE, 413 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c
index aa9512321f3a..06f7922606c0 100644
--- a/drivers/watchdog/pcwd.c
+++ b/drivers/watchdog/pcwd.c
@@ -606,7 +606,7 @@ static long pcwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
606 int temperature; 606 int temperature;
607 int new_heartbeat; 607 int new_heartbeat;
608 int __user *argp = (int __user *)arg; 608 int __user *argp = (int __user *)arg;
609 static struct watchdog_info ident = { 609 static const struct watchdog_info ident = {
610 .options = WDIOF_OVERHEAT | 610 .options = WDIOF_OVERHEAT |
611 WDIOF_CARDRESET | 611 WDIOF_CARDRESET |
612 WDIOF_KEEPALIVEPING | 612 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index 698f51bff1bc..64374d636f09 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -481,7 +481,7 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
481{ 481{
482 void __user *argp = (void __user *)arg; 482 void __user *argp = (void __user *)arg;
483 int __user *p = argp; 483 int __user *p = argp;
484 static struct watchdog_info ident = { 484 static const struct watchdog_info ident = {
485 .options = WDIOF_OVERHEAT | 485 .options = WDIOF_OVERHEAT |
486 WDIOF_CARDRESET | 486 WDIOF_CARDRESET |
487 WDIOF_KEEPALIVEPING | 487 WDIOF_KEEPALIVEPING |
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 052fe451851f..8e4eacc5bb52 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -404,7 +404,7 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
404{ 404{
405 void __user *argp = (void __user *)arg; 405 void __user *argp = (void __user *)arg;
406 int __user *p = argp; 406 int __user *p = argp;
407 static struct watchdog_info ident = { 407 static const struct watchdog_info ident = {
408 .options = WDIOF_KEEPALIVEPING | 408 .options = WDIOF_KEEPALIVEPING |
409 WDIOF_SETTIMEOUT | 409 WDIOF_SETTIMEOUT |
410 WDIOF_MAGICCLOSE, 410 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c
index 2d22e996e996..435ec2aed4fe 100644
--- a/drivers/watchdog/pika_wdt.c
+++ b/drivers/watchdog/pika_wdt.c
@@ -52,7 +52,7 @@ static struct {
52 struct timer_list timer; /* The timer that pings the watchdog */ 52 struct timer_list timer; /* The timer that pings the watchdog */
53} pikawdt_private; 53} pikawdt_private;
54 54
55static struct watchdog_info ident = { 55static const struct watchdog_info ident = {
56 .identity = DRV_NAME, 56 .identity = DRV_NAME,
57 .options = WDIOF_CARDRESET | 57 .options = WDIOF_CARDRESET |
58 WDIOF_SETTIMEOUT | 58 WDIOF_SETTIMEOUT |
diff --git a/drivers/watchdog/pnx833x_wdt.c b/drivers/watchdog/pnx833x_wdt.c
index 538ec2c05197..09102f09e681 100644
--- a/drivers/watchdog/pnx833x_wdt.c
+++ b/drivers/watchdog/pnx833x_wdt.c
@@ -141,7 +141,7 @@ static long pnx833x_wdt_ioctl(struct file *file, unsigned int cmd,
141 int options, new_timeout = 0; 141 int options, new_timeout = 0;
142 uint32_t timeout, timeout_left = 0; 142 uint32_t timeout, timeout_left = 0;
143 143
144 static struct watchdog_info ident = { 144 static const struct watchdog_info ident = {
145 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT, 145 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
146 .firmware_version = 0, 146 .firmware_version = 0,
147 .identity = "Hardware Watchdog for PNX833x", 147 .identity = "Hardware Watchdog for PNX833x",
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index bf12d06b5877..d4c29b5311a4 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -198,7 +198,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
198 void __user *argp = (void __user *)arg; 198 void __user *argp = (void __user *)arg;
199 int new_timeout; 199 int new_timeout;
200 unsigned int value; 200 unsigned int value;
201 static struct watchdog_info ident = { 201 static const struct watchdog_info ident = {
202 .options = WDIOF_SETTIMEOUT | 202 .options = WDIOF_SETTIMEOUT |
203 WDIOF_KEEPALIVEPING | 203 WDIOF_KEEPALIVEPING |
204 WDIOF_MAGICCLOSE, 204 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 4976bfd1fce6..69c6adbd8205 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -149,7 +149,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
149{ 149{
150 void __user *argp = (void __user *)arg; 150 void __user *argp = (void __user *)arg;
151 unsigned int value; 151 unsigned int value;
152 static struct watchdog_info ident = { 152 static const struct watchdog_info ident = {
153 .options = WDIOF_CARDRESET, 153 .options = WDIOF_CARDRESET,
154 .identity = "RDC321x WDT", 154 .identity = "RDC321x WDT",
155 }; 155 };
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index c14ae8676903..ae57bf9e1b03 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -85,7 +85,7 @@ static int riowd_release(struct inode *inode, struct file *filp)
85 85
86static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 86static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
87{ 87{
88 static struct watchdog_info info = { 88 static const struct watchdog_info info = {
89 .options = WDIOF_SETTIMEOUT, 89 .options = WDIOF_SETTIMEOUT,
90 .firmware_version = 1, 90 .firmware_version = 1,
91 .identity = DRIVER_NAME, 91 .identity = DRIVER_NAME,
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
index e6763d2a567b..8d44c9b6fb5b 100644
--- a/drivers/watchdog/sbc_fitpc2_wdt.c
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -111,7 +111,7 @@ out:
111} 111}
112 112
113 113
114static struct watchdog_info ident = { 114static const struct watchdog_info ident = {
115 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | 115 .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
116 WDIOF_KEEPALIVEPING, 116 WDIOF_KEEPALIVEPING,
117 .identity = WATCHDOG_NAME, 117 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c
index 569eb295a7a8..9c40f48804f5 100644
--- a/drivers/watchdog/sch311x_wdt.c
+++ b/drivers/watchdog/sch311x_wdt.c
@@ -250,7 +250,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
250 int new_timeout; 250 int new_timeout;
251 void __user *argp = (void __user *)arg; 251 void __user *argp = (void __user *)arg;
252 int __user *p = argp; 252 int __user *p = argp;
253 static struct watchdog_info ident = { 253 static const struct watchdog_info ident = {
254 .options = WDIOF_KEEPALIVEPING | 254 .options = WDIOF_KEEPALIVEPING |
255 WDIOF_SETTIMEOUT | 255 WDIOF_SETTIMEOUT |
256 WDIOF_MAGICCLOSE, 256 WDIOF_MAGICCLOSE,
diff --git a/drivers/watchdog/stmp3xxx_wdt.c b/drivers/watchdog/stmp3xxx_wdt.c
index 5dd952681f32..b3421fd2cda8 100644
--- a/drivers/watchdog/stmp3xxx_wdt.c
+++ b/drivers/watchdog/stmp3xxx_wdt.c
@@ -94,7 +94,7 @@ static ssize_t stmp3xxx_wdt_write(struct file *file, const char __user *data,
94 return len; 94 return len;
95} 95}
96 96
97static struct watchdog_info ident = { 97static const struct watchdog_info ident = {
98 .options = WDIOF_CARDRESET | 98 .options = WDIOF_CARDRESET |
99 WDIOF_MAGICCLOSE | 99 WDIOF_MAGICCLOSE |
100 WDIOF_SETTIMEOUT | 100 WDIOF_SETTIMEOUT |
diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c
new file mode 100644
index 000000000000..565a2c3321e5
--- /dev/null
+++ b/drivers/watchdog/ts72xx_wdt.c
@@ -0,0 +1,520 @@
1/*
2 * Watchdog driver for Technologic Systems TS-72xx based SBCs
3 * (TS-7200, TS-7250 and TS-7260). These boards have external
4 * glue logic CPLD chip, which includes programmable watchdog
5 * timer.
6 *
7 * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
8 *
9 * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
10 *
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
14 */
15
16#include <linux/fs.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/miscdevice.h>
21#include <linux/mutex.h>
22#include <linux/platform_device.h>
23#include <linux/watchdog.h>
24#include <linux/uaccess.h>
25
26#define TS72XX_WDT_FEED_VAL 0x05
27#define TS72XX_WDT_DEFAULT_TIMEOUT 8
28
29static int timeout = TS72XX_WDT_DEFAULT_TIMEOUT;
30module_param(timeout, int, 0);
31MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. "
32 "(1 <= timeout <= 8, default="
33 __MODULE_STRING(TS72XX_WDT_DEFAULT_TIMEOUT)
34 ")");
35
36static int nowayout = WATCHDOG_NOWAYOUT;
37module_param(nowayout, int, 0);
38MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
39
40/**
41 * struct ts72xx_wdt - watchdog control structure
42 * @lock: lock that protects this structure
43 * @regval: watchdog timeout value suitable for control register
44 * @flags: flags controlling watchdog device state
45 * @control_reg: watchdog control register
46 * @feed_reg: watchdog feed register
47 * @pdev: back pointer to platform dev
48 */
49struct ts72xx_wdt {
50 struct mutex lock;
51 int regval;
52
53#define TS72XX_WDT_BUSY_FLAG 1
54#define TS72XX_WDT_EXPECT_CLOSE_FLAG 2
55 int flags;
56
57 void __iomem *control_reg;
58 void __iomem *feed_reg;
59
60 struct platform_device *pdev;
61};
62
63struct platform_device *ts72xx_wdt_pdev;
64
65/*
66 * TS-72xx Watchdog supports following timeouts (value written
67 * to control register):
68 * value description
69 * -------------------------
70 * 0x00 watchdog disabled
71 * 0x01 250ms
72 * 0x02 500ms
73 * 0x03 1s
74 * 0x04 reserved
75 * 0x05 2s
76 * 0x06 4s
77 * 0x07 8s
78 *
79 * Timeouts below 1s are not very usable so we don't
80 * allow them at all.
81 *
82 * We provide two functions that convert between these:
83 * timeout_to_regval() and regval_to_timeout().
84 */
85static const struct {
86 int timeout;
87 int regval;
88} ts72xx_wdt_map[] = {
89 { 1, 3 },
90 { 2, 5 },
91 { 4, 6 },
92 { 8, 7 },
93};
94
95/**
96 * timeout_to_regval() - converts given timeout to control register value
97 * @new_timeout: timeout in seconds to be converted
98 *
99 * Function converts given @new_timeout into valid value that can
100 * be programmed into watchdog control register. When conversion is
101 * not possible, function returns %-EINVAL.
102 */
103static int timeout_to_regval(int new_timeout)
104{
105 int i;
106
107 /* first limit it to 1 - 8 seconds */
108 new_timeout = clamp_val(new_timeout, 1, 8);
109
110 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
111 if (ts72xx_wdt_map[i].timeout >= new_timeout)
112 return ts72xx_wdt_map[i].regval;
113 }
114
115 return -EINVAL;
116}
117
118/**
119 * regval_to_timeout() - converts control register value to timeout
120 * @regval: control register value to be converted
121 *
122 * Function converts given @regval to timeout in seconds (1, 2, 4 or 8).
123 * If @regval cannot be converted, function returns %-EINVAL.
124 */
125static int regval_to_timeout(int regval)
126{
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(ts72xx_wdt_map); i++) {
130 if (ts72xx_wdt_map[i].regval == regval)
131 return ts72xx_wdt_map[i].timeout;
132 }
133
134 return -EINVAL;
135}
136
137/**
138 * ts72xx_wdt_kick() - kick the watchdog
139 * @wdt: watchdog to be kicked
140 *
141 * Called with @wdt->lock held.
142 */
143static inline void ts72xx_wdt_kick(struct ts72xx_wdt *wdt)
144{
145 __raw_writeb(TS72XX_WDT_FEED_VAL, wdt->feed_reg);
146}
147
148/**
149 * ts72xx_wdt_start() - starts the watchdog timer
150 * @wdt: watchdog to be started
151 *
152 * This function programs timeout to watchdog timer
153 * and starts it.
154 *
155 * Called with @wdt->lock held.
156 */
157static void ts72xx_wdt_start(struct ts72xx_wdt *wdt)
158{
159 /*
160 * To program the wdt, it first must be "fed" and
161 * only after that (within 30 usecs) the configuration
162 * can be changed.
163 */
164 ts72xx_wdt_kick(wdt);
165 __raw_writeb((u8)wdt->regval, wdt->control_reg);
166}
167
168/**
169 * ts72xx_wdt_stop() - stops the watchdog timer
170 * @wdt: watchdog to be stopped
171 *
172 * Called with @wdt->lock held.
173 */
174static void ts72xx_wdt_stop(struct ts72xx_wdt *wdt)
175{
176 ts72xx_wdt_kick(wdt);
177 __raw_writeb(0, wdt->control_reg);
178}
179
180static int ts72xx_wdt_open(struct inode *inode, struct file *file)
181{
182 struct ts72xx_wdt *wdt = platform_get_drvdata(ts72xx_wdt_pdev);
183 int regval;
184
185 /*
186 * Try to convert default timeout to valid register
187 * value first.
188 */
189 regval = timeout_to_regval(timeout);
190 if (regval < 0) {
191 dev_err(&wdt->pdev->dev,
192 "failed to convert timeout (%d) to register value\n",
193 timeout);
194 return -EINVAL;
195 }
196
197 if (mutex_lock_interruptible(&wdt->lock))
198 return -ERESTARTSYS;
199
200 if ((wdt->flags & TS72XX_WDT_BUSY_FLAG) != 0) {
201 mutex_unlock(&wdt->lock);
202 return -EBUSY;
203 }
204
205 wdt->flags = TS72XX_WDT_BUSY_FLAG;
206 wdt->regval = regval;
207 file->private_data = wdt;
208
209 ts72xx_wdt_start(wdt);
210
211 mutex_unlock(&wdt->lock);
212 return nonseekable_open(inode, file);
213}
214
215static int ts72xx_wdt_release(struct inode *inode, struct file *file)
216{
217 struct ts72xx_wdt *wdt = file->private_data;
218
219 if (mutex_lock_interruptible(&wdt->lock))
220 return -ERESTARTSYS;
221
222 if ((wdt->flags & TS72XX_WDT_EXPECT_CLOSE_FLAG) != 0) {
223 ts72xx_wdt_stop(wdt);
224 } else {
225 dev_warn(&wdt->pdev->dev,
226 "TS-72XX WDT device closed unexpectly. "
227 "Watchdog timer will not stop!\n");
228 /*
229 * Kick it one more time, to give userland some time
230 * to recover (for example, respawning the kicker
231 * daemon).
232 */
233 ts72xx_wdt_kick(wdt);
234 }
235
236 wdt->flags = 0;
237
238 mutex_unlock(&wdt->lock);
239 return 0;
240}
241
242static ssize_t ts72xx_wdt_write(struct file *file,
243 const char __user *data,
244 size_t len,
245 loff_t *ppos)
246{
247 struct ts72xx_wdt *wdt = file->private_data;
248
249 if (!len)
250 return 0;
251
252 if (mutex_lock_interruptible(&wdt->lock))
253 return -ERESTARTSYS;
254
255 ts72xx_wdt_kick(wdt);
256
257 /*
258 * Support for magic character closing. User process
259 * writes 'V' into the device, just before it is closed.
260 * This means that we know that the wdt timer can be
261 * stopped after user closes the device.
262 */
263 if (!nowayout) {
264 int i;
265
266 for (i = 0; i < len; i++) {
267 char c;
268
269 /* In case it was set long ago */
270 wdt->flags &= ~TS72XX_WDT_EXPECT_CLOSE_FLAG;
271
272 if (get_user(c, data + i)) {
273 mutex_unlock(&wdt->lock);
274 return -EFAULT;
275 }
276 if (c == 'V') {
277 wdt->flags |= TS72XX_WDT_EXPECT_CLOSE_FLAG;
278 break;
279 }
280 }
281 }
282
283 mutex_unlock(&wdt->lock);
284 return len;
285}
286
287static const struct watchdog_info winfo = {
288 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
289 WDIOF_MAGICCLOSE,
290 .firmware_version = 1,
291 .identity = "TS-72XX WDT",
292};
293
294static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd,
295 unsigned long arg)
296{
297 struct ts72xx_wdt *wdt = file->private_data;
298 void __user *argp = (void __user *)arg;
299 int __user *p = (int __user *)argp;
300 int error = 0;
301
302 if (mutex_lock_interruptible(&wdt->lock))
303 return -ERESTARTSYS;
304
305 switch (cmd) {
306 case WDIOC_GETSUPPORT:
307 error = copy_to_user(argp, &winfo, sizeof(winfo));
308 break;
309
310 case WDIOC_GETSTATUS:
311 case WDIOC_GETBOOTSTATUS:
312 return put_user(0, p);
313
314 case WDIOC_KEEPALIVE:
315 ts72xx_wdt_kick(wdt);
316 break;
317
318 case WDIOC_SETOPTIONS: {
319 int options;
320
321 if (get_user(options, p)) {
322 error = -EFAULT;
323 break;
324 }
325
326 error = -EINVAL;
327
328 if ((options & WDIOS_DISABLECARD) != 0) {
329 ts72xx_wdt_stop(wdt);
330 error = 0;
331 }
332 if ((options & WDIOS_ENABLECARD) != 0) {
333 ts72xx_wdt_start(wdt);
334 error = 0;
335 }
336
337 break;
338 }
339
340 case WDIOC_SETTIMEOUT: {
341 int new_timeout;
342
343 if (get_user(new_timeout, p)) {
344 error = -EFAULT;
345 } else {
346 int regval;
347
348 regval = timeout_to_regval(new_timeout);
349 if (regval < 0) {
350 error = -EINVAL;
351 } else {
352 ts72xx_wdt_stop(wdt);
353 wdt->regval = regval;
354 ts72xx_wdt_start(wdt);
355 }
356 }
357 if (error)
358 break;
359
360 /*FALLTHROUGH*/
361 }
362
363 case WDIOC_GETTIMEOUT:
364 if (put_user(regval_to_timeout(wdt->regval), p))
365 error = -EFAULT;
366 break;
367
368 default:
369 error = -ENOTTY;
370 break;
371 }
372
373 mutex_unlock(&wdt->lock);
374 return error;
375}
376
377static const struct file_operations ts72xx_wdt_fops = {
378 .owner = THIS_MODULE,
379 .llseek = no_llseek,
380 .open = ts72xx_wdt_open,
381 .release = ts72xx_wdt_release,
382 .write = ts72xx_wdt_write,
383 .unlocked_ioctl = ts72xx_wdt_ioctl,
384};
385
386static struct miscdevice ts72xx_wdt_miscdev = {
387 .minor = WATCHDOG_MINOR,
388 .name = "watchdog",
389 .fops = &ts72xx_wdt_fops,
390};
391
392static __devinit int ts72xx_wdt_probe(struct platform_device *pdev)
393{
394 struct ts72xx_wdt *wdt;
395 struct resource *r1, *r2;
396 int error = 0;
397
398 wdt = kzalloc(sizeof(struct ts72xx_wdt), GFP_KERNEL);
399 if (!wdt) {
400 dev_err(&pdev->dev, "failed to allocate memory\n");
401 return -ENOMEM;
402 }
403
404 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
405 if (!r1) {
406 dev_err(&pdev->dev, "failed to get memory resource\n");
407 error = -ENODEV;
408 goto fail;
409 }
410
411 r1 = request_mem_region(r1->start, resource_size(r1), pdev->name);
412 if (!r1) {
413 dev_err(&pdev->dev, "cannot request memory region\n");
414 error = -EBUSY;
415 goto fail;
416 }
417
418 wdt->control_reg = ioremap(r1->start, resource_size(r1));
419 if (!wdt->control_reg) {
420 dev_err(&pdev->dev, "failed to map memory\n");
421 error = -ENODEV;
422 goto fail_free_control;
423 }
424
425 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
426 if (!r2) {
427 dev_err(&pdev->dev, "failed to get memory resource\n");
428 error = -ENODEV;
429 goto fail_unmap_control;
430 }
431
432 r2 = request_mem_region(r2->start, resource_size(r2), pdev->name);
433 if (!r2) {
434 dev_err(&pdev->dev, "cannot request memory region\n");
435 error = -EBUSY;
436 goto fail_unmap_control;
437 }
438
439 wdt->feed_reg = ioremap(r2->start, resource_size(r2));
440 if (!wdt->feed_reg) {
441 dev_err(&pdev->dev, "failed to map memory\n");
442 error = -ENODEV;
443 goto fail_free_feed;
444 }
445
446 platform_set_drvdata(pdev, wdt);
447 ts72xx_wdt_pdev = pdev;
448 wdt->pdev = pdev;
449 mutex_init(&wdt->lock);
450
451 error = misc_register(&ts72xx_wdt_miscdev);
452 if (error) {
453 dev_err(&pdev->dev, "failed to register miscdev\n");
454 goto fail_unmap_feed;
455 }
456
457 dev_info(&pdev->dev, "TS-72xx Watchdog driver\n");
458
459 return 0;
460
461fail_unmap_feed:
462 platform_set_drvdata(pdev, NULL);
463 iounmap(wdt->feed_reg);
464fail_free_feed:
465 release_mem_region(r2->start, resource_size(r2));
466fail_unmap_control:
467 iounmap(wdt->control_reg);
468fail_free_control:
469 release_mem_region(r1->start, resource_size(r1));
470fail:
471 kfree(wdt);
472 return error;
473}
474
475static __devexit int ts72xx_wdt_remove(struct platform_device *pdev)
476{
477 struct ts72xx_wdt *wdt = platform_get_drvdata(pdev);
478 struct resource *res;
479 int error;
480
481 error = misc_deregister(&ts72xx_wdt_miscdev);
482 platform_set_drvdata(pdev, NULL);
483
484 iounmap(wdt->feed_reg);
485 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
486 release_mem_region(res->start, resource_size(res));
487
488 iounmap(wdt->control_reg);
489 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
490 release_mem_region(res->start, resource_size(res));
491
492 kfree(wdt);
493 return error;
494}
495
496static struct platform_driver ts72xx_wdt_driver = {
497 .probe = ts72xx_wdt_probe,
498 .remove = __devexit_p(ts72xx_wdt_remove),
499 .driver = {
500 .name = "ts72xx-wdt",
501 .owner = THIS_MODULE,
502 },
503};
504
505static __init int ts72xx_wdt_init(void)
506{
507 return platform_driver_register(&ts72xx_wdt_driver);
508}
509module_init(ts72xx_wdt_init);
510
511static __exit void ts72xx_wdt_exit(void)
512{
513 platform_driver_unregister(&ts72xx_wdt_driver);
514}
515module_exit(ts72xx_wdt_exit);
516
517MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
518MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
519MODULE_LICENSE("GPL");
520MODULE_ALIAS("platform:ts72xx-wdt");
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index d635566e9307..9e9ed7bfabcb 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -13,7 +13,6 @@
13#include <linux/miscdevice.h> 13#include <linux/miscdevice.h>
14#include <linux/watchdog.h> 14#include <linux/watchdog.h>
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/reboot.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/uaccess.h> 17#include <linux/uaccess.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
@@ -166,14 +165,6 @@ static long txx9wdt_ioctl(struct file *file, unsigned int cmd,
166 } 165 }
167} 166}
168 167
169static int txx9wdt_notify_sys(struct notifier_block *this, unsigned long code,
170 void *unused)
171{
172 if (code == SYS_DOWN || code == SYS_HALT)
173 txx9wdt_stop();
174 return NOTIFY_DONE;
175}
176
177static const struct file_operations txx9wdt_fops = { 168static const struct file_operations txx9wdt_fops = {
178 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
179 .llseek = no_llseek, 170 .llseek = no_llseek,
@@ -189,10 +180,6 @@ static struct miscdevice txx9wdt_miscdev = {
189 .fops = &txx9wdt_fops, 180 .fops = &txx9wdt_fops,
190}; 181};
191 182
192static struct notifier_block txx9wdt_notifier = {
193 .notifier_call = txx9wdt_notify_sys,
194};
195
196static int __init txx9wdt_probe(struct platform_device *dev) 183static int __init txx9wdt_probe(struct platform_device *dev)
197{ 184{
198 struct resource *res; 185 struct resource *res;
@@ -221,13 +208,8 @@ static int __init txx9wdt_probe(struct platform_device *dev)
221 if (!txx9wdt_reg) 208 if (!txx9wdt_reg)
222 goto exit_busy; 209 goto exit_busy;
223 210
224 ret = register_reboot_notifier(&txx9wdt_notifier);
225 if (ret)
226 goto exit;
227
228 ret = misc_register(&txx9wdt_miscdev); 211 ret = misc_register(&txx9wdt_miscdev);
229 if (ret) { 212 if (ret) {
230 unregister_reboot_notifier(&txx9wdt_notifier);
231 goto exit; 213 goto exit;
232 } 214 }
233 215
@@ -249,14 +231,19 @@ exit:
249static int __exit txx9wdt_remove(struct platform_device *dev) 231static int __exit txx9wdt_remove(struct platform_device *dev)
250{ 232{
251 misc_deregister(&txx9wdt_miscdev); 233 misc_deregister(&txx9wdt_miscdev);
252 unregister_reboot_notifier(&txx9wdt_notifier);
253 clk_disable(txx9_imclk); 234 clk_disable(txx9_imclk);
254 clk_put(txx9_imclk); 235 clk_put(txx9_imclk);
255 return 0; 236 return 0;
256} 237}
257 238
239static void txx9wdt_shutdown(struct platform_device *dev)
240{
241 txx9wdt_stop();
242}
243
258static struct platform_driver txx9wdt_driver = { 244static struct platform_driver txx9wdt_driver = {
259 .remove = __exit_p(txx9wdt_remove), 245 .remove = __exit_p(txx9wdt_remove),
246 .shutdown = txx9wdt_shutdown,
260 .driver = { 247 .driver = {
261 .name = "txx9wdt", 248 .name = "txx9wdt",
262 .owner = THIS_MODULE, 249 .owner = THIS_MODULE,
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c
index f201accc4e3d..0f5288df0091 100644
--- a/drivers/watchdog/w83627hf_wdt.c
+++ b/drivers/watchdog/w83627hf_wdt.c
@@ -201,7 +201,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
201 void __user *argp = (void __user *)arg; 201 void __user *argp = (void __user *)arg;
202 int __user *p = argp; 202 int __user *p = argp;
203 int new_timeout; 203 int new_timeout;
204 static struct watchdog_info ident = { 204 static const struct watchdog_info ident = {
205 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | 205 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
206 WDIOF_MAGICCLOSE, 206 WDIOF_MAGICCLOSE,
207 .firmware_version = 1, 207 .firmware_version = 1,
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c
index 0560182a1d09..6e6743d1066f 100644
--- a/drivers/watchdog/w83977f_wdt.c
+++ b/drivers/watchdog/w83977f_wdt.c
@@ -371,7 +371,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf,
371 * according to their available features. 371 * according to their available features.
372 */ 372 */
373 373
374static struct watchdog_info ident = { 374static const struct watchdog_info ident = {
375 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, 375 .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
376 .firmware_version = 1, 376 .firmware_version = 1,
377 .identity = WATCHDOG_NAME, 377 .identity = WATCHDOG_NAME,
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c
index 5bfb1f2c5319..94ec22b9e66b 100644
--- a/drivers/watchdog/wdrtas.c
+++ b/drivers/watchdog/wdrtas.c
@@ -312,7 +312,7 @@ static long wdrtas_ioctl(struct file *file, unsigned int cmd,
312{ 312{
313 int __user *argp = (void __user *)arg; 313 int __user *argp = (void __user *)arg;
314 int i; 314 int i;
315 static struct watchdog_info wdinfo = { 315 static const struct watchdog_info wdinfo = {
316 .options = WDRTAS_SUPPORTED_MASK, 316 .options = WDRTAS_SUPPORTED_MASK,
317 .firmware_version = 0, 317 .firmware_version = 0,
318 .identity = "wdrtas", 318 .identity = "wdrtas",
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c
index 3bbefe9a2634..bfda2e99dd89 100644
--- a/drivers/watchdog/wdt.c
+++ b/drivers/watchdog/wdt.c
@@ -358,7 +358,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
358 int new_heartbeat; 358 int new_heartbeat;
359 int status; 359 int status;
360 360
361 static struct watchdog_info ident = { 361 struct watchdog_info ident = {
362 .options = WDIOF_SETTIMEOUT| 362 .options = WDIOF_SETTIMEOUT|
363 WDIOF_MAGICCLOSE| 363 WDIOF_MAGICCLOSE|
364 WDIOF_KEEPALIVEPING, 364 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index f368dd87083a..7b22e3cdbc81 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -412,7 +412,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
412 int new_heartbeat; 412 int new_heartbeat;
413 int status; 413 int status;
414 414
415 static struct watchdog_info ident = { 415 struct watchdog_info ident = {
416 .options = WDIOF_SETTIMEOUT| 416 .options = WDIOF_SETTIMEOUT|
417 WDIOF_MAGICCLOSE| 417 WDIOF_MAGICCLOSE|
418 WDIOF_KEEPALIVEPING, 418 WDIOF_KEEPALIVEPING,
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 775bcd807f31..8c4b2d5bb7da 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -213,7 +213,7 @@ static ssize_t wm831x_wdt_write(struct file *file,
213 return count; 213 return count;
214} 214}
215 215
216static struct watchdog_info ident = { 216static const struct watchdog_info ident = {
217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 217 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
218 .identity = "WM831x Watchdog", 218 .identity = "WM831x Watchdog",
219}; 219};
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index a2d2e8eb2282..89dd7b035295 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -177,7 +177,7 @@ static ssize_t wm8350_wdt_write(struct file *file,
177 return count; 177 return count;
178} 178}
179 179
180static struct watchdog_info ident = { 180static const struct watchdog_info ident = {
181 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, 181 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
182 .identity = "WM8350 Watchdog", 182 .identity = "WM8350 Watchdog",
183}; 183};
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
index 864dac20a242..cc94bb9563f2 100644
--- a/fs/fscache/Kconfig
+++ b/fs/fscache/Kconfig
@@ -1,7 +1,6 @@
1 1
2config FSCACHE 2config FSCACHE
3 tristate "General filesystem local caching manager" 3 tristate "General filesystem local caching manager"
4 depends on EXPERIMENTAL
5 select SLOW_WORK 4 select SLOW_WORK
6 help 5 help
7 This option enables a generic filesystem caching manager that can be 6 This option enables a generic filesystem caching manager that can be
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h
index 6bb293684eb8..4d3e450e2b03 100644
--- a/include/linux/usb/audio.h
+++ b/include/linux/usb/audio.h
@@ -269,8 +269,8 @@ struct uac_format_type_i_ext_descriptor {
269 __u8 bLength; 269 __u8 bLength;
270 __u8 bDescriptorType; 270 __u8 bDescriptorType;
271 __u8 bDescriptorSubtype; 271 __u8 bDescriptorSubtype;
272 __u8 bSubslotSize;
273 __u8 bFormatType; 272 __u8 bFormatType;
273 __u8 bSubslotSize;
274 __u8 bBitResolution; 274 __u8 bBitResolution;
275 __u8 bHeaderLength; 275 __u8 bHeaderLength;
276 __u8 bControlSize; 276 __u8 bControlSize;
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 1f57bb92eb5a..098595500632 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -544,7 +544,7 @@ struct snd_rawmidi_status {
544 * Timer section - /dev/snd/timer 544 * Timer section - /dev/snd/timer
545 */ 545 */
546 546
547#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 5) 547#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
548 548
549enum { 549enum {
550 SNDRV_TIMER_CLASS_NONE = -1, 550 SNDRV_TIMER_CLASS_NONE = -1,
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 8f8b17ac074d..73943651caed 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -393,7 +393,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
393 event == SNDRV_TIMER_EVENT_CONTINUE) 393 event == SNDRV_TIMER_EVENT_CONTINUE)
394 resolution = snd_timer_resolution(ti); 394 resolution = snd_timer_resolution(ti);
395 if (ti->ccallback) 395 if (ti->ccallback)
396 ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); 396 ti->ccallback(ti, event, &tstamp, resolution);
397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE) 397 if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
398 return; 398 return;
399 timer = ti->timer; 399 timer = ti->timer;
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index b865e45a8f9b..5913717c1be6 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1558,7 +1558,7 @@ static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
1558 1558
1559 err = pnp_activate_dev(devmc); 1559 err = pnp_activate_dev(devmc);
1560 if (err < 0) { 1560 if (err < 0) {
1561 snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n", 1561 snd_printk(KERN_ERR "MC pnp configure failure: %d\n",
1562 err); 1562 err);
1563 return err; 1563 return err;
1564 } 1564 }
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index a4af53b5c1cf..becd90d7536d 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -144,12 +144,8 @@ struct snd_opti9xx {
144 144
145 spinlock_t lock; 145 spinlock_t lock;
146 146
147 long wss_base;
147 int irq; 148 int irq;
148
149#ifdef CONFIG_PNP
150 struct pnp_dev *dev;
151 struct pnp_dev *devmpu;
152#endif /* CONFIG_PNP */
153}; 149};
154 150
155static int snd_opti9xx_pnp_is_probed; 151static int snd_opti9xx_pnp_is_probed;
@@ -159,12 +155,17 @@ static int snd_opti9xx_pnp_is_probed;
159static struct pnp_card_device_id snd_opti9xx_pnpids[] = { 155static struct pnp_card_device_id snd_opti9xx_pnpids[] = {
160#ifndef OPTi93X 156#ifndef OPTi93X
161 /* OPTi 82C924 */ 157 /* OPTi 82C924 */
162 { .id = "OPT0924", .devs = { { "OPT0000" }, { "OPT0002" } }, .driver_data = 0x0924 }, 158 { .id = "OPT0924",
159 .devs = { { "OPT0000" }, { "OPT0002" }, { "OPT0005" } },
160 .driver_data = 0x0924 },
163 /* OPTi 82C925 */ 161 /* OPTi 82C925 */
164 { .id = "OPT0925", .devs = { { "OPT9250" }, { "OPT0002" } }, .driver_data = 0x0925 }, 162 { .id = "OPT0925",
163 .devs = { { "OPT9250" }, { "OPT0002" }, { "OPT0005" } },
164 .driver_data = 0x0925 },
165#else 165#else
166 /* OPTi 82C931/3 */ 166 /* OPTi 82C931/3 */
167 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } }, .driver_data = 0x0931 }, 167 { .id = "OPT0931", .devs = { { "OPT9310" }, { "OPT0002" } },
168 .driver_data = 0x0931 },
168#endif /* OPTi93X */ 169#endif /* OPTi93X */
169 { .id = "" } 170 { .id = "" }
170}; 171};
@@ -207,24 +208,34 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
207 chip->hardware = hardware; 208 chip->hardware = hardware;
208 strcpy(chip->name, snd_opti9xx_names[hardware]); 209 strcpy(chip->name, snd_opti9xx_names[hardware]);
209 210
210 chip->mc_base_size = opti9xx_mc_size[hardware];
211
212 spin_lock_init(&chip->lock); 211 spin_lock_init(&chip->lock);
213 212
214 chip->irq = -1; 213 chip->irq = -1;
215 214
215#ifndef OPTi93X
216#ifdef CONFIG_PNP
217 if (isapnp && chip->mc_base)
218 /* PnP resource gives the least 10 bits */
219 chip->mc_base |= 0xc00;
220#endif /* CONFIG_PNP */
221 else {
222 chip->mc_base = 0xf8c;
223 chip->mc_base_size = opti9xx_mc_size[hardware];
224 }
225#else
226 chip->mc_base_size = opti9xx_mc_size[hardware];
227#endif
228
216 switch (hardware) { 229 switch (hardware) {
217#ifndef OPTi93X 230#ifndef OPTi93X
218 case OPTi9XX_HW_82C928: 231 case OPTi9XX_HW_82C928:
219 case OPTi9XX_HW_82C929: 232 case OPTi9XX_HW_82C929:
220 chip->mc_base = 0xf8c;
221 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3; 233 chip->password = (hardware == OPTi9XX_HW_82C928) ? 0xe2 : 0xe3;
222 chip->pwd_reg = 3; 234 chip->pwd_reg = 3;
223 break; 235 break;
224 236
225 case OPTi9XX_HW_82C924: 237 case OPTi9XX_HW_82C924:
226 case OPTi9XX_HW_82C925: 238 case OPTi9XX_HW_82C925:
227 chip->mc_base = 0xf8c;
228 chip->password = 0xe5; 239 chip->password = 0xe5;
229 chip->pwd_reg = 3; 240 chip->pwd_reg = 3;
230 break; 241 break;
@@ -292,7 +303,7 @@ static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
292 spin_unlock_irqrestore(&chip->lock, flags); 303 spin_unlock_irqrestore(&chip->lock, flags);
293 return retval; 304 return retval;
294} 305}
295 306
296static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, 307static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
297 unsigned char value) 308 unsigned char value)
298{ 309{
@@ -341,7 +352,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
341 352
342 353
343static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 354static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
344 long wss_base, 355 long port,
345 int irq, int dma1, int dma2, 356 int irq, int dma1, int dma2,
346 long mpu_port, int mpu_irq) 357 long mpu_port, int mpu_irq)
347{ 358{
@@ -354,16 +365,23 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
354 switch (chip->hardware) { 365 switch (chip->hardware) {
355#ifndef OPTi93X 366#ifndef OPTi93X
356 case OPTi9XX_HW_82C924: 367 case OPTi9XX_HW_82C924:
368 /* opti 929 mode (?), OPL3 clock output, audio enable */
357 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc); 369 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(4), 0xf0, 0xfc);
370 /* enable wave audio */
358 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 371 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
359 372
360 case OPTi9XX_HW_82C925: 373 case OPTi9XX_HW_82C925:
374 /* enable WSS mode */
361 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80); 375 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
376 /* OPL3 FM synthesis */
362 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20); 377 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 0x00, 0x20);
378 /* disable Sound Blaster IRQ and DMA */
363 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 379 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
364#ifdef CS4231 380#ifdef CS4231
381 /* cs4231/4248 fix enabled */
365 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02); 382 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
366#else 383#else
384 /* cs4231/4248 fix disabled */
367 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02); 385 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(5), 0x00, 0x02);
368#endif /* CS4231 */ 386#endif /* CS4231 */
369 break; 387 break;
@@ -411,21 +429,26 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
411 return -EINVAL; 429 return -EINVAL;
412 } 430 }
413 431
414 switch (wss_base) { 432 /* PnP resource says it decodes only 10 bits of address */
415 case 0x530: 433 switch (port & 0x3ff) {
434 case 0x130:
435 chip->wss_base = 0x530;
416 wss_base_bits = 0x00; 436 wss_base_bits = 0x00;
417 break; 437 break;
418 case 0x604: 438 case 0x204:
439 chip->wss_base = 0x604;
419 wss_base_bits = 0x03; 440 wss_base_bits = 0x03;
420 break; 441 break;
421 case 0xe80: 442 case 0x280:
443 chip->wss_base = 0xe80;
422 wss_base_bits = 0x01; 444 wss_base_bits = 0x01;
423 break; 445 break;
424 case 0xf40: 446 case 0x340:
447 chip->wss_base = 0xf40;
425 wss_base_bits = 0x02; 448 wss_base_bits = 0x02;
426 break; 449 break;
427 default: 450 default:
428 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base); 451 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", port);
429 goto __skip_base; 452 goto __skip_base;
430 } 453 }
431 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); 454 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
@@ -487,7 +510,7 @@ __skip_base:
487#endif /* CS4231 || OPTi93X */ 510#endif /* CS4231 || OPTi93X */
488 511
489#ifndef OPTi93X 512#ifndef OPTi93X
490 outb(irq_bits << 3 | dma_bits, wss_base); 513 outb(irq_bits << 3 | dma_bits, chip->wss_base);
491#else /* OPTi93X */ 514#else /* OPTi93X */
492 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); 515 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
493#endif /* OPTi93X */ 516#endif /* OPTi93X */
@@ -729,15 +752,15 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
729{ 752{
730 struct pnp_dev *pdev; 753 struct pnp_dev *pdev;
731 int err; 754 int err;
755 struct pnp_dev *devmpu;
756#ifndef OPTi93X
757 struct pnp_dev *devmc;
758#endif
732 759
733 chip->dev = pnp_request_card_device(card, pid->devs[0].id, NULL); 760 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
734 if (chip->dev == NULL) 761 if (pdev == NULL)
735 return -EBUSY; 762 return -EBUSY;
736 763
737 chip->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
738
739 pdev = chip->dev;
740
741 err = pnp_activate_dev(pdev); 764 err = pnp_activate_dev(pdev);
742 if (err < 0) { 765 if (err < 0) {
743 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err); 766 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
@@ -750,9 +773,24 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
750 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; 773 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
751 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; 774 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
752#else 775#else
753 if (pid->driver_data != 0x0924) 776 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
754 port = pnp_port_start(pdev, 1); 777 if (devmc == NULL)
778 return -EBUSY;
779
780 err = pnp_activate_dev(devmc);
781 if (err < 0) {
782 snd_printk(KERN_ERR "MC pnp configure failure: %d\n", err);
783 return err;
784 }
785
786 port = pnp_port_start(pdev, 1);
755 fm_port = pnp_port_start(pdev, 2) + 8; 787 fm_port = pnp_port_start(pdev, 2) + 8;
788 /*
789 * The MC(0) is never accessed and card does not
790 * include it in the PnP resource range. OPTI93x include it.
791 */
792 chip->mc_base = pnp_port_start(devmc, 0) - 1;
793 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
756#endif /* OPTi93X */ 794#endif /* OPTi93X */
757 irq = pnp_irq(pdev, 0); 795 irq = pnp_irq(pdev, 0);
758 dma1 = pnp_dma(pdev, 0); 796 dma1 = pnp_dma(pdev, 0);
@@ -760,16 +798,16 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
760 dma2 = pnp_dma(pdev, 1); 798 dma2 = pnp_dma(pdev, 1);
761#endif /* CS4231 || OPTi93X */ 799#endif /* CS4231 || OPTi93X */
762 800
763 pdev = chip->devmpu; 801 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
764 if (pdev && mpu_port > 0) { 802
765 err = pnp_activate_dev(pdev); 803 if (devmpu && mpu_port > 0) {
804 err = pnp_activate_dev(devmpu);
766 if (err < 0) { 805 if (err < 0) {
767 snd_printk(KERN_ERR "AUDIO pnp configure failure\n"); 806 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
768 mpu_port = -1; 807 mpu_port = -1;
769 chip->devmpu = NULL;
770 } else { 808 } else {
771 mpu_port = pnp_port_start(pdev, 0); 809 mpu_port = pnp_port_start(devmpu, 0);
772 mpu_irq = pnp_irq(pdev, 0); 810 mpu_irq = pnp_irq(devmpu, 0);
773 } 811 }
774 } 812 }
775 return pid->driver_data; 813 return pid->driver_data;
@@ -824,7 +862,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
824 if (error) 862 if (error)
825 return error; 863 return error;
826 864
827 error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2, 865 error = snd_wss_create(card, chip->wss_base + 4, -1, irq, dma1, xdma2,
828#ifdef OPTi93X 866#ifdef OPTi93X
829 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, 867 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
830#else 868#else
@@ -865,10 +903,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
865 sprintf(card->shortname, "OPTi %s", card->driver); 903 sprintf(card->shortname, "OPTi %s", card->driver);
866#if defined(CS4231) || defined(OPTi93X) 904#if defined(CS4231) || defined(OPTi93X)
867 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 905 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
868 card->shortname, pcm->name, port + 4, irq, dma1, xdma2); 906 card->shortname, pcm->name,
907 chip->wss_base + 4, irq, dma1, xdma2);
869#else 908#else
870 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", 909 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
871 card->shortname, pcm->name, port + 4, irq, dma1); 910 card->shortname, pcm->name, chip->wss_base + 4, irq, dma1);
872#endif /* CS4231 || OPTi93X */ 911#endif /* CS4231 || OPTi93X */
873 912
874 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) 913 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
@@ -1062,9 +1101,6 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
1062 snd_card_free(card); 1101 snd_card_free(card);
1063 return error; 1102 return error;
1064 } 1103 }
1065 if (hw <= OPTi9XX_HW_82C930)
1066 chip->mc_base -= 0x80;
1067
1068 error = snd_opti9xx_read_check(chip); 1104 error = snd_opti9xx_read_check(chip);
1069 if (error) { 1105 if (error) {
1070 snd_printk(KERN_ERR "OPTI chip not found\n"); 1106 snd_printk(KERN_ERR "OPTI chip not found\n");
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 8d21a3feda3a..8ccbcddf08e1 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/delay.h>
17#include <asm/dma.h> 18#include <asm/dma.h>
18#include <linux/isa.h> 19#include <linux/isa.h>
19#include <sound/core.h> 20#include <sound/core.h>
diff --git a/sound/oss/coproc.h b/sound/oss/coproc.h
index 7306346e9ac4..7bec21bbdd88 100644
--- a/sound/oss/coproc.h
+++ b/sound/oss/coproc.h
@@ -4,7 +4,7 @@
4 */ 4 */
5 5
6/* 6/*
7 * Coprocessor access types 7 * Coprocessor access types
8 */ 8 */
9#define COPR_CUSTOM 0x0001 /* Custom applications */ 9#define COPR_CUSTOM 0x0001 /* Custom applications */
10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */ 10#define COPR_MIDI 0x0002 /* MIDI (MPU-401) emulation */
diff --git a/sound/oss/v_midi.h b/sound/oss/v_midi.h
index 1b86cb45c607..08e2185ee816 100644
--- a/sound/oss/v_midi.h
+++ b/sound/oss/v_midi.h
@@ -2,9 +2,9 @@ typedef struct vmidi_devc {
2 int dev; 2 int dev;
3 3
4 /* State variables */ 4 /* State variables */
5 int opened; 5 int opened;
6 spinlock_t lock; 6 spinlock_t lock;
7 7
8 /* MIDI fields */ 8 /* MIDI fields */
9 int my_mididev; 9 int my_mididev;
10 int pair_mididev; 10 int pair_mididev;
@@ -12,4 +12,3 @@ typedef struct vmidi_devc {
12 int intr_active; 12 int intr_active;
13 void (*midi_input_intr) (int dev, unsigned char data); 13 void (*midi_input_intr) (int dev, unsigned char data);
14 } vmidi_devc; 14 } vmidi_devc;
15
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 556cff937be7..567348b05b5a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
157 157
158config SND_HDA_ELD 158config SND_HDA_ELD
159 def_bool y 159 def_bool y
160 depends on SND_HDA_CODEC_INTELHDMI 160 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
161 161
162config SND_HDA_CODEC_CIRRUS 162config SND_HDA_CODEC_CIRRUS
163 bool "Build Cirrus Logic codec support" 163 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 315a1c4f8998..24bc195b02da 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o 6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 9
@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 18snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 19snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o 21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 22
23# common driver 23# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 76d3c4c049db..5bd7cf45f3a5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
978 * 978 *
979 * Returns 0 if successful, or a negative error code. 979 * Returns 0 if successful, or a negative error code.
980 */ 980 */
981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
982 struct hda_codec **codecp) 982 unsigned int codec_addr,
983 struct hda_codec **codecp)
983{ 984{
984 struct hda_codec *codec; 985 struct hda_codec *codec;
985 char component[31]; 986 char component[31];
@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1186 */ 1187 */
1187 1188
1188/* FIXME: more better hash key? */ 1189/* FIXME: more better hash key? */
1189#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) 1190#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1190#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) 1191#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1191#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) 1192#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1192#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) 1193#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1356 if (!codec->no_trigger_sense) { 1357 if (!codec->no_trigger_sense) {
1357 pincap = snd_hda_query_pin_caps(codec, nid); 1358 pincap = snd_hda_query_pin_caps(codec, nid);
1358 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 1359 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1359 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); 1360 snd_hda_codec_read(codec, nid, 0,
1361 AC_VERB_SET_PIN_SENSE, 0);
1360 } 1362 }
1361 return snd_hda_codec_read(codec, nid, 0, 1363 return snd_hda_codec_read(codec, nid, 0,
1362 AC_VERB_GET_PIN_SENSE, 0); 1364 AC_VERB_GET_PIN_SENSE, 0);
@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1372 */ 1374 */
1373int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 1375int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1374{ 1376{
1375 u32 sense = snd_hda_pin_sense(codec, nid); 1377 u32 sense = snd_hda_pin_sense(codec, nid);
1376 return !!(sense & AC_PINSENSE_PRESENCE); 1378 return !!(sense & AC_PINSENSE_PRESENCE);
1377} 1379}
1378EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 1380EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1379 1381
@@ -1952,7 +1954,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1952 err = snd_hda_ctl_add(codec, 0, kctl); 1954 err = snd_hda_ctl_add(codec, 0, kctl);
1953 if (err < 0) 1955 if (err < 0)
1954 return err; 1956 return err;
1955 1957
1956 for (s = slaves; *s; s++) { 1958 for (s = slaves; *s; s++) {
1957 struct snd_kcontrol *sctl; 1959 struct snd_kcontrol *sctl;
1958 int i = 0; 1960 int i = 0;
@@ -2439,27 +2441,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
2439 { 2441 {
2440 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2442 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2442 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 2444 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
2443 .info = snd_hda_spdif_mask_info, 2445 .info = snd_hda_spdif_mask_info,
2444 .get = snd_hda_spdif_cmask_get, 2446 .get = snd_hda_spdif_cmask_get,
2445 }, 2447 },
2446 { 2448 {
2447 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2449 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2449 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 2451 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
2450 .info = snd_hda_spdif_mask_info, 2452 .info = snd_hda_spdif_mask_info,
2451 .get = snd_hda_spdif_pmask_get, 2453 .get = snd_hda_spdif_pmask_get,
2452 }, 2454 },
2453 { 2455 {
2454 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2455 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2457 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
2456 .info = snd_hda_spdif_mask_info, 2458 .info = snd_hda_spdif_mask_info,
2457 .get = snd_hda_spdif_default_get, 2459 .get = snd_hda_spdif_default_get,
2458 .put = snd_hda_spdif_default_put, 2460 .put = snd_hda_spdif_default_put,
2459 }, 2461 },
2460 { 2462 {
2461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2462 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2464 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
2463 .info = snd_hda_spdif_out_switch_info, 2465 .info = snd_hda_spdif_out_switch_info,
2464 .get = snd_hda_spdif_out_switch_get, 2466 .get = snd_hda_spdif_out_switch_get,
2465 .put = snd_hda_spdif_out_switch_put, 2467 .put = snd_hda_spdif_out_switch_put,
@@ -2610,7 +2612,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2610static struct snd_kcontrol_new dig_in_ctls[] = { 2612static struct snd_kcontrol_new dig_in_ctls[] = {
2611 { 2613 {
2612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2613 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 2615 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
2614 .info = snd_hda_spdif_in_switch_info, 2616 .info = snd_hda_spdif_in_switch_info,
2615 .get = snd_hda_spdif_in_switch_get, 2617 .get = snd_hda_spdif_in_switch_get,
2616 .put = snd_hda_spdif_in_switch_put, 2618 .put = snd_hda_spdif_in_switch_put,
@@ -2618,7 +2620,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
2618 { 2620 {
2619 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2621 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2620 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2621 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 2623 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
2622 .info = snd_hda_spdif_mask_info, 2624 .info = snd_hda_spdif_mask_info,
2623 .get = snd_hda_spdif_in_status_get, 2625 .get = snd_hda_spdif_in_status_get,
2624 }, 2626 },
@@ -2883,7 +2885,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
2883 int err = snd_hda_codec_build_controls(codec); 2885 int err = snd_hda_codec_build_controls(codec);
2884 if (err < 0) { 2886 if (err < 0) {
2885 printk(KERN_ERR "hda_codec: cannot build controls" 2887 printk(KERN_ERR "hda_codec: cannot build controls"
2886 "for #%d (error %d)\n", codec->addr, err); 2888 "for #%d (error %d)\n", codec->addr, err);
2887 err = snd_hda_codec_reset(codec); 2889 err = snd_hda_codec_reset(codec);
2888 if (err < 0) { 2890 if (err < 0) {
2889 printk(KERN_ERR 2891 printk(KERN_ERR
@@ -2979,8 +2981,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2979 val |= channels - 1; 2981 val |= channels - 1;
2980 2982
2981 switch (snd_pcm_format_width(format)) { 2983 switch (snd_pcm_format_width(format)) {
2982 case 8: val |= 0x00; break; 2984 case 8:
2983 case 16: val |= 0x10; break; 2985 val |= 0x00;
2986 break;
2987 case 16:
2988 val |= 0x10;
2989 break;
2984 case 20: 2990 case 20:
2985 case 24: 2991 case 24:
2986 case 32: 2992 case 32:
@@ -3298,7 +3304,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
3298 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) 3304 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3299 return audio_idx[type][i]; 3305 return audio_idx[type][i];
3300 3306
3301 snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); 3307 snd_printk(KERN_WARNING "Too many %s devices\n",
3308 snd_hda_pcm_type_name[type]);
3302 return -EAGAIN; 3309 return -EAGAIN;
3303} 3310}
3304 3311
@@ -3336,7 +3343,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
3336 err = codec->patch_ops.build_pcms(codec); 3343 err = codec->patch_ops.build_pcms(codec);
3337 if (err < 0) { 3344 if (err < 0) {
3338 printk(KERN_ERR "hda_codec: cannot build PCMs" 3345 printk(KERN_ERR "hda_codec: cannot build PCMs"
3339 "for #%d (error %d)\n", codec->addr, err); 3346 "for #%d (error %d)\n", codec->addr, err);
3340 err = snd_hda_codec_reset(codec); 3347 err = snd_hda_codec_reset(codec);
3341 if (err < 0) { 3348 if (err < 0) {
3342 printk(KERN_ERR 3349 printk(KERN_ERR
@@ -3466,8 +3473,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3466 3473
3467/** 3474/**
3468 * snd_hda_check_board_codec_sid_config - compare the current codec 3475 * snd_hda_check_board_codec_sid_config - compare the current codec
3469 subsystem ID with the 3476 subsystem ID with the
3470 config table 3477 config table
3471 3478
3472 This is important for Gateway notebooks with SB450 HDA Audio 3479 This is important for Gateway notebooks with SB450 HDA Audio
3473 where the vendor ID of the PCI device is: 3480 where the vendor ID of the PCI device is:
@@ -3607,7 +3614,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
3607 * 3614 *
3608 * Increment the power-up counter and power up the hardware really when 3615 * Increment the power-up counter and power up the hardware really when
3609 * not turned on yet. 3616 * not turned on yet.
3610 */ 3617 */
3611void snd_hda_power_up(struct hda_codec *codec) 3618void snd_hda_power_up(struct hda_codec *codec)
3612{ 3619{
3613 struct hda_bus *bus = codec->bus; 3620 struct hda_bus *bus = codec->bus;
@@ -3636,7 +3643,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
3636 * 3643 *
3637 * Decrement the power-up counter and schedules the power-off work if 3644 * Decrement the power-up counter and schedules the power-off work if
3638 * the counter rearches to zero. 3645 * the counter rearches to zero.
3639 */ 3646 */
3640void snd_hda_power_down(struct hda_codec *codec) 3647void snd_hda_power_down(struct hda_codec *codec)
3641{ 3648{
3642 --codec->power_count; 3649 --codec->power_count;
@@ -3662,7 +3669,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down);
3662 * 3669 *
3663 * This function is supposed to be set or called from the check_power_status 3670 * This function is supposed to be set or called from the check_power_status
3664 * patch ops. 3671 * patch ops.
3665 */ 3672 */
3666int snd_hda_check_amp_list_power(struct hda_codec *codec, 3673int snd_hda_check_amp_list_power(struct hda_codec *codec,
3667 struct hda_loopback_check *check, 3674 struct hda_loopback_check *check,
3668 hda_nid_t nid) 3675 hda_nid_t nid)
@@ -3830,7 +3837,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3830{ 3837{
3831 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 3838 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
3832 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 3839 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3833 set_dig_out_convert(codec, nid, 3840 set_dig_out_convert(codec, nid,
3834 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 3841 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3835 -1); 3842 -1);
3836 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 3843 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -4089,13 +4096,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
4089/* 4096/*
4090 * Sort an associated group of pins according to their sequence numbers. 4097 * Sort an associated group of pins according to their sequence numbers.
4091 */ 4098 */
4092static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, 4099static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4093 int num_pins) 4100 int num_pins)
4094{ 4101{
4095 int i, j; 4102 int i, j;
4096 short seq; 4103 short seq;
4097 hda_nid_t nid; 4104 hda_nid_t nid;
4098 4105
4099 for (i = 0; i < num_pins; i++) { 4106 for (i = 0; i < num_pins; i++) {
4100 for (j = i + 1; j < num_pins; j++) { 4107 for (j = i + 1; j < num_pins; j++) {
4101 if (sequences[i] > sequences[j]) { 4108 if (sequences[i] > sequences[j]) {
@@ -4123,7 +4130,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
4123 * is detected, one of speaker of HP pins is assigned as the primary 4130 * is detected, one of speaker of HP pins is assigned as the primary
4124 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4131 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4125 * if any analog output exists. 4132 * if any analog output exists.
4126 * 4133 *
4127 * The analog input pins are assigned to input_pins array. 4134 * The analog input pins are assigned to input_pins array.
4128 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4135 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4129 * respectively. 4136 * respectively.
@@ -4186,9 +4193,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4186 case AC_JACK_SPEAKER: 4193 case AC_JACK_SPEAKER:
4187 seq = get_defcfg_sequence(def_conf); 4194 seq = get_defcfg_sequence(def_conf);
4188 assoc = get_defcfg_association(def_conf); 4195 assoc = get_defcfg_association(def_conf);
4189 if (! assoc) 4196 if (!assoc)
4190 continue; 4197 continue;
4191 if (! assoc_speaker) 4198 if (!assoc_speaker)
4192 assoc_speaker = assoc; 4199 assoc_speaker = assoc;
4193 else if (assoc_speaker != assoc) 4200 else if (assoc_speaker != assoc)
4194 continue; 4201 continue;
@@ -4286,7 +4293,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4286 cfg->speaker_outs); 4293 cfg->speaker_outs);
4287 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4294 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4288 cfg->hp_outs); 4295 cfg->hp_outs);
4289 4296
4290 /* if we have only one mic, make it AUTO_PIN_MIC */ 4297 /* if we have only one mic, make it AUTO_PIN_MIC */
4291 if (!cfg->input_pins[AUTO_PIN_MIC] && 4298 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4292 cfg->input_pins[AUTO_PIN_FRONT_MIC]) { 4299 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
@@ -4436,7 +4443,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
4436/** 4443/**
4437 * snd_array_new - get a new element from the given array 4444 * snd_array_new - get a new element from the given array
4438 * @array: the array object 4445 * @array: the array object
4439 * 4446 *
4440 * Get a new element from the given array. If it exceeds the 4447 * Get a new element from the given array. If it exceeds the
4441 * pre-allocated array size, re-allocate the array. 4448 * pre-allocated array size, re-allocate the array.
4442 * 4449 *
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 4228f2fe5956..dcd22446cfc7 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -331,6 +331,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
332 AC_DIPSIZE_ELD_BUF); 332 AC_DIPSIZE_ELD_BUF);
333} 333}
334EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
334 335
335int snd_hdmi_get_eld(struct hdmi_eld *eld, 336int snd_hdmi_get_eld(struct hdmi_eld *eld,
336 struct hda_codec *codec, hda_nid_t nid) 337 struct hda_codec *codec, hda_nid_t nid)
@@ -366,6 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
366 kfree(buf); 367 kfree(buf);
367 return ret; 368 return ret;
368} 369}
370EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
369 371
370static void hdmi_show_short_audio_desc(struct cea_sad *a) 372static void hdmi_show_short_audio_desc(struct cea_sad *a)
371{ 373{
@@ -404,6 +406,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
404 } 406 }
405 buf[j] = '\0'; /* necessary when j == 0 */ 407 buf[j] = '\0'; /* necessary when j == 0 */
406} 408}
409EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
407 410
408void snd_hdmi_show_eld(struct hdmi_eld *e) 411void snd_hdmi_show_eld(struct hdmi_eld *e)
409{ 412{
@@ -422,6 +425,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
422 for (i = 0; i < e->sad_count; i++) 425 for (i = 0; i < e->sad_count; i++)
423 hdmi_show_short_audio_desc(e->sad + i); 426 hdmi_show_short_audio_desc(e->sad + i);
424} 427}
428EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
425 429
426#ifdef CONFIG_PROC_FS 430#ifdef CONFIG_PROC_FS
427 431
@@ -580,6 +584,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
580 584
581 return 0; 585 return 0;
582} 586}
587EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
583 588
584void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 589void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
585{ 590{
@@ -588,5 +593,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
588 eld->proc_entry = NULL; 593 eld->proc_entry = NULL;
589 } 594 }
590} 595}
596EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
591 597
592#endif /* CONFIG_PROC_FS */ 598#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index d5c93ad852ee..43b7cfb7cffd 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -267,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
267#define RIRB_INT_MASK 0x05 267#define RIRB_INT_MASK 0x05
268 268
269/* STATESTS int mask: S3,SD2,SD1,SD0 */ 269/* STATESTS int mask: S3,SD2,SD1,SD0 */
270#define AZX_MAX_CODECS 4 270#define AZX_MAX_CODECS 8
271#define AZX_DEFAULT_CODECS 4
271#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1) 272#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
272 273
273/* SD_CTL bits */ 274/* SD_CTL bits */
@@ -1367,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1367 1368
1368/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ 1369/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
1369static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { 1370static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1371 [AZX_DRIVER_NVIDIA] = 8,
1370 [AZX_DRIVER_TERA] = 1, 1372 [AZX_DRIVER_TERA] = 1,
1371}; 1373};
1372 1374
@@ -1399,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1399 codecs = 0; 1401 codecs = 0;
1400 max_slots = azx_max_codecs[chip->driver_type]; 1402 max_slots = azx_max_codecs[chip->driver_type];
1401 if (!max_slots) 1403 if (!max_slots)
1402 max_slots = AZX_MAX_CODECS; 1404 max_slots = AZX_DEFAULT_CODECS;
1403 1405
1404 /* First try to probe all given codec slots */ 1406 /* First try to probe all given codec slots */
1405 for (c = 0; c < max_slots; c++) { 1407 for (c = 0; c < max_slots; c++) {
@@ -2263,10 +2265,12 @@ static int azx_dev_free(struct snd_device *device)
2263static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2265static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2264 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2267 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2267 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2270 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2271 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2269 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2272 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2273 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2270 {} 2274 {}
2271}; 2275};
2272 2276
@@ -2354,6 +2358,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2354static struct snd_pci_quirk msi_black_list[] __devinitdata = { 2358static struct snd_pci_quirk msi_black_list[] __devinitdata = {
2355 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ 2359 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
2356 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ 2360 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
2361 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
2357 {} 2362 {}
2358}; 2363};
2359 2364
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 000000000000..2c2bafbf0258
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,849 @@
1/*
2 *
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com>
9 *
10 * Maintained by:
11 * Wu Fengguang <wfg@linux.intel.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28
29struct hdmi_spec {
30 int num_cvts;
31 int num_pins;
32 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
33 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
34
35 /*
36 * source connection for each pin
37 */
38 hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
39
40 /*
41 * HDMI sink attached to each pin
42 */
43 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
44
45 /*
46 * export one pcm per pipe
47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49
50 /*
51 * nvhdmi specific
52 */
53 struct hda_multi_out multiout;
54 unsigned int codec_type;
55};
56
57
58struct hdmi_audio_infoframe {
59 u8 type; /* 0x84 */
60 u8 ver; /* 0x01 */
61 u8 len; /* 0x0a */
62
63 u8 checksum; /* PB0 */
64 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
65 u8 SS01_SF24;
66 u8 CXT04;
67 u8 CA;
68 u8 LFEPBL01_LSV36_DM_INH7;
69 u8 reserved[5]; /* PB6 - PB10 */
70};
71
72/*
73 * CEA speaker placement:
74 *
75 * FLH FCH FRH
76 * FLW FL FLC FC FRC FR FRW
77 *
78 * LFE
79 * TC
80 *
81 * RL RLC RC RRC RR
82 *
83 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
84 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
85 */
86enum cea_speaker_placement {
87 FL = (1 << 0), /* Front Left */
88 FC = (1 << 1), /* Front Center */
89 FR = (1 << 2), /* Front Right */
90 FLC = (1 << 3), /* Front Left Center */
91 FRC = (1 << 4), /* Front Right Center */
92 RL = (1 << 5), /* Rear Left */
93 RC = (1 << 6), /* Rear Center */
94 RR = (1 << 7), /* Rear Right */
95 RLC = (1 << 8), /* Rear Left Center */
96 RRC = (1 << 9), /* Rear Right Center */
97 LFE = (1 << 10), /* Low Frequency Effect */
98 FLW = (1 << 11), /* Front Left Wide */
99 FRW = (1 << 12), /* Front Right Wide */
100 FLH = (1 << 13), /* Front Left High */
101 FCH = (1 << 14), /* Front Center High */
102 FRH = (1 << 15), /* Front Right High */
103 TC = (1 << 16), /* Top Center */
104};
105
106/*
107 * ELD SA bits in the CEA Speaker Allocation data block
108 */
109static int eld_speaker_allocation_bits[] = {
110 [0] = FL | FR,
111 [1] = LFE,
112 [2] = FC,
113 [3] = RL | RR,
114 [4] = RC,
115 [5] = FLC | FRC,
116 [6] = RLC | RRC,
117 /* the following are not defined in ELD yet */
118 [7] = FLW | FRW,
119 [8] = FLH | FRH,
120 [9] = TC,
121 [10] = FCH,
122};
123
124struct cea_channel_speaker_allocation {
125 int ca_index;
126 int speakers[8];
127
128 /* derived values, just for convenience */
129 int channels;
130 int spk_mask;
131};
132
133/*
134 * ALSA sequence is:
135 *
136 * surround40 surround41 surround50 surround51 surround71
137 * ch0 front left = = = =
138 * ch1 front right = = = =
139 * ch2 rear left = = = =
140 * ch3 rear right = = = =
141 * ch4 LFE center center center
142 * ch5 LFE LFE
143 * ch6 side left
144 * ch7 side right
145 *
146 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
147 */
148static int hdmi_channel_mapping[0x32][8] = {
149 /* stereo */
150 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
151 /* 2.1 */
152 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
153 /* Dolby Surround */
154 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
155 /* surround40 */
156 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
157 /* 4ch */
158 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
159 /* surround41 */
160 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
161 /* surround50 */
162 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
163 /* surround51 */
164 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
165 /* 7.1 */
166 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
167};
168
169/*
170 * This is an ordered list!
171 *
172 * The preceding ones have better chances to be selected by
173 * hdmi_setup_channel_allocation().
174 */
175static struct cea_channel_speaker_allocation channel_allocations[] = {
176/* channel: 7 6 5 4 3 2 1 0 */
177{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
178 /* 2.1 */
179{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
180 /* Dolby Surround */
181{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
182 /* surround40 */
183{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
184 /* surround41 */
185{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
186 /* surround50 */
187{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
188 /* surround51 */
189{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
190 /* 6.1 */
191{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
192 /* surround71 */
193{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
194
195{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
196{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
197{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
198{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
199{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
200{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
203{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
204{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
205{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
206{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
207{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
208{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
209{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
210{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
211{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
212{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
213{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
214{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
215{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
216{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
217{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
218{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
219{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
220{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
222{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
223{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
224{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
225{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
226{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
227{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
228{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
229{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
230{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
231{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
232{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
233{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
234{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
235{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
236};
237
238
239/*
240 * HDMI routines
241 */
242
243static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
244{
245 int i;
246
247 for (i = 0; nids[i]; i++)
248 if (nids[i] == nid)
249 return i;
250
251 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
252 return -EINVAL;
253}
254
255static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
256 struct hdmi_eld *eld)
257{
258 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
259 snd_hdmi_show_eld(eld);
260}
261
262#ifdef BE_PARANOID
263static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
264 int *packet_index, int *byte_index)
265{
266 int val;
267
268 val = snd_hda_codec_read(codec, pin_nid, 0,
269 AC_VERB_GET_HDMI_DIP_INDEX, 0);
270
271 *packet_index = val >> 5;
272 *byte_index = val & 0x1f;
273}
274#endif
275
276static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
277 int packet_index, int byte_index)
278{
279 int val;
280
281 val = (packet_index << 5) | (byte_index & 0x1f);
282
283 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
284}
285
286static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
287 unsigned char val)
288{
289 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
290}
291
292static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
293{
294 /* Unmute */
295 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
296 snd_hda_codec_write(codec, pin_nid, 0,
297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
298 /* Enable pin out */
299 snd_hda_codec_write(codec, pin_nid, 0,
300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
301}
302
303static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
304{
305 return 1 + snd_hda_codec_read(codec, nid, 0,
306 AC_VERB_GET_CVT_CHAN_COUNT, 0);
307}
308
309static void hdmi_set_channel_count(struct hda_codec *codec,
310 hda_nid_t nid, int chs)
311{
312 if (chs != hdmi_get_channel_count(codec, nid))
313 snd_hda_codec_write(codec, nid, 0,
314 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
315}
316
317
318/*
319 * Channel mapping routines
320 */
321
322/*
323 * Compute derived values in channel_allocations[].
324 */
325static void init_channel_allocations(void)
326{
327 int i, j;
328 struct cea_channel_speaker_allocation *p;
329
330 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
331 p = channel_allocations + i;
332 p->channels = 0;
333 p->spk_mask = 0;
334 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
335 if (p->speakers[j]) {
336 p->channels++;
337 p->spk_mask |= p->speakers[j];
338 }
339 }
340}
341
342/*
343 * The transformation takes two steps:
344 *
345 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
346 * spk_mask => (channel_allocations[]) => ai->CA
347 *
348 * TODO: it could select the wrong CA from multiple candidates.
349*/
350static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
351 struct hdmi_audio_infoframe *ai)
352{
353 struct hdmi_spec *spec = codec->spec;
354 struct hdmi_eld *eld;
355 int i;
356 int spk_mask = 0;
357 int channels = 1 + (ai->CC02_CT47 & 0x7);
358 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
359
360 /*
361 * CA defaults to 0 for basic stereo audio
362 */
363 if (channels <= 2)
364 return 0;
365
366 i = hda_node_index(spec->pin_cvt, nid);
367 if (i < 0)
368 return 0;
369 eld = &spec->sink_eld[i];
370
371 /*
372 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
373 * in console or for audio devices. Assume the highest speakers
374 * configuration, to _not_ prohibit multi-channel audio playback.
375 */
376 if (!eld->spk_alloc)
377 eld->spk_alloc = 0xffff;
378
379 /*
380 * expand ELD's speaker allocation mask
381 *
382 * ELD tells the speaker mask in a compact(paired) form,
383 * expand ELD's notions to match the ones used by Audio InfoFrame.
384 */
385 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
386 if (eld->spk_alloc & (1 << i))
387 spk_mask |= eld_speaker_allocation_bits[i];
388 }
389
390 /* search for the first working match in the CA table */
391 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
392 if (channels == channel_allocations[i].channels &&
393 (spk_mask & channel_allocations[i].spk_mask) ==
394 channel_allocations[i].spk_mask) {
395 ai->CA = channel_allocations[i].ca_index;
396 break;
397 }
398 }
399
400 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
401 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
402 ai->CA, channels, buf);
403
404 return ai->CA;
405}
406
407static void hdmi_debug_channel_mapping(struct hda_codec *codec,
408 hda_nid_t pin_nid)
409{
410#ifdef CONFIG_SND_DEBUG_VERBOSE
411 int i;
412 int slot;
413
414 for (i = 0; i < 8; i++) {
415 slot = snd_hda_codec_read(codec, pin_nid, 0,
416 AC_VERB_GET_HDMI_CHAN_SLOT, i);
417 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
418 slot >> 4, slot & 0xf);
419 }
420#endif
421}
422
423
424static void hdmi_setup_channel_mapping(struct hda_codec *codec,
425 hda_nid_t pin_nid,
426 struct hdmi_audio_infoframe *ai)
427{
428 int i;
429 int ca = ai->CA;
430 int err;
431
432 if (hdmi_channel_mapping[ca][1] == 0) {
433 for (i = 0; i < channel_allocations[ca].channels; i++)
434 hdmi_channel_mapping[ca][i] = i | (i << 4);
435 for (; i < 8; i++)
436 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
437 }
438
439 for (i = 0; i < 8; i++) {
440 err = snd_hda_codec_write(codec, pin_nid, 0,
441 AC_VERB_SET_HDMI_CHAN_SLOT,
442 hdmi_channel_mapping[ca][i]);
443 if (err) {
444 snd_printdd(KERN_NOTICE
445 "HDMI: channel mapping failed\n");
446 break;
447 }
448 }
449
450 hdmi_debug_channel_mapping(codec, pin_nid);
451}
452
453
454/*
455 * Audio InfoFrame routines
456 */
457
458/*
459 * Enable Audio InfoFrame Transmission
460 */
461static void hdmi_start_infoframe_trans(struct hda_codec *codec,
462 hda_nid_t pin_nid)
463{
464 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
466 AC_DIPXMIT_BEST);
467}
468
469/*
470 * Disable Audio InfoFrame Transmission
471 */
472static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
473 hda_nid_t pin_nid)
474{
475 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
476 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
477 AC_DIPXMIT_DISABLE);
478}
479
480static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
481{
482#ifdef CONFIG_SND_DEBUG_VERBOSE
483 int i;
484 int size;
485
486 size = snd_hdmi_get_eld_size(codec, pin_nid);
487 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
488
489 for (i = 0; i < 8; i++) {
490 size = snd_hda_codec_read(codec, pin_nid, 0,
491 AC_VERB_GET_HDMI_DIP_SIZE, i);
492 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
493 }
494#endif
495}
496
497static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
498{
499#ifdef BE_PARANOID
500 int i, j;
501 int size;
502 int pi, bi;
503 for (i = 0; i < 8; i++) {
504 size = snd_hda_codec_read(codec, pin_nid, 0,
505 AC_VERB_GET_HDMI_DIP_SIZE, i);
506 if (size == 0)
507 continue;
508
509 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
510 for (j = 1; j < 1000; j++) {
511 hdmi_write_dip_byte(codec, pin_nid, 0x0);
512 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
513 if (pi != i)
514 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
515 bi, pi, i);
516 if (bi == 0) /* byte index wrapped around */
517 break;
518 }
519 snd_printd(KERN_INFO
520 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
521 i, size, j);
522 }
523#endif
524}
525
526static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
527{
528 u8 *bytes = (u8 *)ai;
529 u8 sum = 0;
530 int i;
531
532 ai->checksum = 0;
533
534 for (i = 0; i < sizeof(*ai); i++)
535 sum += bytes[i];
536
537 ai->checksum = -sum;
538}
539
540static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
541 hda_nid_t pin_nid,
542 struct hdmi_audio_infoframe *ai)
543{
544 u8 *bytes = (u8 *)ai;
545 int i;
546
547 hdmi_debug_dip_size(codec, pin_nid);
548 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
549
550 hdmi_checksum_audio_infoframe(ai);
551
552 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
553 for (i = 0; i < sizeof(*ai); i++)
554 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
555}
556
557static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
558 struct hdmi_audio_infoframe *ai)
559{
560 u8 *bytes = (u8 *)ai;
561 u8 val;
562 int i;
563
564 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
565 != AC_DIPXMIT_BEST)
566 return false;
567
568 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
569 for (i = 0; i < sizeof(*ai); i++) {
570 val = snd_hda_codec_read(codec, pin_nid, 0,
571 AC_VERB_GET_HDMI_DIP_DATA, 0);
572 if (val != bytes[i])
573 return false;
574 }
575
576 return true;
577}
578
579static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
580 struct snd_pcm_substream *substream)
581{
582 struct hdmi_spec *spec = codec->spec;
583 hda_nid_t pin_nid;
584 int i;
585 struct hdmi_audio_infoframe ai = {
586 .type = 0x84,
587 .ver = 0x01,
588 .len = 0x0a,
589 .CC02_CT47 = substream->runtime->channels - 1,
590 };
591
592 hdmi_setup_channel_allocation(codec, nid, &ai);
593
594 for (i = 0; i < spec->num_pins; i++) {
595 if (spec->pin_cvt[i] != nid)
596 continue;
597 if (!spec->sink_eld[i].monitor_present)
598 continue;
599
600 pin_nid = spec->pin[i];
601 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
602 snd_printdd("hdmi_setup_audio_infoframe: "
603 "cvt=%d pin=%d channels=%d\n",
604 nid, pin_nid,
605 substream->runtime->channels);
606 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
607 hdmi_stop_infoframe_trans(codec, pin_nid);
608 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
609 hdmi_start_infoframe_trans(codec, pin_nid);
610 }
611 }
612}
613
614
615/*
616 * Unsolicited events
617 */
618
619static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
620{
621 struct hdmi_spec *spec = codec->spec;
622 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
623 int pind = !!(res & AC_UNSOL_RES_PD);
624 int eldv = !!(res & AC_UNSOL_RES_ELDV);
625 int index;
626
627 printk(KERN_INFO
628 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
629 tag, pind, eldv);
630
631 index = hda_node_index(spec->pin, tag);
632 if (index < 0)
633 return;
634
635 spec->sink_eld[index].monitor_present = pind;
636 spec->sink_eld[index].eld_valid = eldv;
637
638 if (pind && eldv) {
639 hdmi_get_show_eld(codec, spec->pin[index],
640 &spec->sink_eld[index]);
641 /* TODO: do real things about ELD */
642 }
643}
644
645static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
646{
647 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
648 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
649 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
650 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
651
652 printk(KERN_INFO
653 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
654 tag,
655 subtag,
656 cp_state,
657 cp_ready);
658
659 /* TODO */
660 if (cp_state)
661 ;
662 if (cp_ready)
663 ;
664}
665
666
667static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
668{
669 struct hdmi_spec *spec = codec->spec;
670 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
671 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
672
673 if (hda_node_index(spec->pin, tag) < 0) {
674 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
675 return;
676 }
677
678 if (subtag == 0)
679 hdmi_intrinsic_event(codec, res);
680 else
681 hdmi_non_intrinsic_event(codec, res);
682}
683
684/*
685 * Callbacks
686 */
687
688static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
689 u32 stream_tag, int format)
690{
691 int tag;
692 int fmt;
693
694 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
695 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
696
697 snd_printdd("hdmi_setup_stream: "
698 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
699 nid,
700 tag == stream_tag ? "" : "new-",
701 stream_tag,
702 fmt == format ? "" : "new-",
703 format);
704
705 if (tag != stream_tag)
706 snd_hda_codec_write(codec, nid, 0,
707 AC_VERB_SET_CHANNEL_STREAMID,
708 stream_tag << 4);
709 if (fmt != format)
710 snd_hda_codec_write(codec, nid, 0,
711 AC_VERB_SET_STREAM_FORMAT, format);
712}
713
714/*
715 * HDA/HDMI auto parsing
716 */
717
718static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
719{
720 struct hdmi_spec *spec = codec->spec;
721 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
722 int conn_len, curr;
723 int index;
724
725 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
726 snd_printk(KERN_WARNING
727 "HDMI: pin %d wcaps %#x "
728 "does not support connection list\n",
729 pin_nid, get_wcaps(codec, pin_nid));
730 return -EINVAL;
731 }
732
733 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
734 HDA_MAX_CONNECTIONS);
735 if (conn_len > 1)
736 curr = snd_hda_codec_read(codec, pin_nid, 0,
737 AC_VERB_GET_CONNECT_SEL, 0);
738 else
739 curr = 0;
740
741 index = hda_node_index(spec->pin, pin_nid);
742 if (index < 0)
743 return -EINVAL;
744
745 spec->pin_cvt[index] = conn_list[curr];
746
747 return 0;
748}
749
750static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
751 struct hdmi_eld *eld)
752{
753 int present = snd_hda_pin_sense(codec, pin_nid);
754
755 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
756 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
757
758 if (present & AC_PINSENSE_ELDV)
759 hdmi_get_show_eld(codec, pin_nid, eld);
760}
761
762static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
763{
764 struct hdmi_spec *spec = codec->spec;
765
766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL;
770 }
771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
773
774 spec->pin[spec->num_pins] = pin_nid;
775 spec->num_pins++;
776
777 /*
778 * It is assumed that converter nodes come first in the node list and
779 * hence have been registered and usable now.
780 */
781 return hdmi_read_pin_conn(codec, pin_nid);
782}
783
784static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
785{
786 struct hdmi_spec *spec = codec->spec;
787
788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL;
792 }
793
794 spec->cvt[spec->num_cvts] = nid;
795 spec->num_cvts++;
796
797 return 0;
798}
799
800static int hdmi_parse_codec(struct hda_codec *codec)
801{
802 hda_nid_t nid;
803 int i, nodes;
804
805 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
806 if (!nid || nodes < 0) {
807 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
808 return -EINVAL;
809 }
810
811 for (i = 0; i < nodes; i++, nid++) {
812 unsigned int caps;
813 unsigned int type;
814
815 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
816 type = get_wcaps_type(caps);
817
818 if (!(caps & AC_WCAP_DIGITAL))
819 continue;
820
821 switch (type) {
822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0)
824 return -EINVAL;
825 break;
826 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue;
830 if (hdmi_add_pin(codec, nid) < 0)
831 return -EINVAL;
832 break;
833 }
834 }
835
836 /*
837 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
838 * can be lost and presence sense verb will become inaccurate if the
839 * HDA link is powered off at hot plug or hw initialization time.
840 */
841#ifdef CONFIG_SND_HDA_POWER_SAVE
842 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
843 AC_PWRST_EPSS))
844 codec->bus->power_keep_link_on = 1;
845#endif
846
847 return 0;
848}
849
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 918f40378d52..88d035104cc5 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,815 +40,20 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define INTEL_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 2
44#define INTEL_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = { 46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
47 "INTEL HDMI 0", 49 "INTEL HDMI 0",
48 "INTEL HDMI 1", 50 "INTEL HDMI 1",
49}; 51};
50 52
51struct intel_hdmi_spec {
52 int num_cvts;
53 int num_pins;
54 hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
55 hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
56
57 /*
58 * source connection for each pin
59 */
60 hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
61
62 /*
63 * HDMI sink attached to each pin
64 */
65 struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
66
67 /*
68 * export one pcm per pipe
69 */
70 struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
71};
72
73struct hdmi_audio_infoframe {
74 u8 type; /* 0x84 */
75 u8 ver; /* 0x01 */
76 u8 len; /* 0x0a */
77
78 u8 checksum; /* PB0 */
79 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
80 u8 SS01_SF24;
81 u8 CXT04;
82 u8 CA;
83 u8 LFEPBL01_LSV36_DM_INH7;
84 u8 reserved[5]; /* PB6 - PB10 */
85};
86
87/*
88 * CEA speaker placement:
89 *
90 * FLH FCH FRH
91 * FLW FL FLC FC FRC FR FRW
92 *
93 * LFE
94 * TC
95 *
96 * RL RLC RC RRC RR
97 *
98 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
99 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
100 */
101enum cea_speaker_placement {
102 FL = (1 << 0), /* Front Left */
103 FC = (1 << 1), /* Front Center */
104 FR = (1 << 2), /* Front Right */
105 FLC = (1 << 3), /* Front Left Center */
106 FRC = (1 << 4), /* Front Right Center */
107 RL = (1 << 5), /* Rear Left */
108 RC = (1 << 6), /* Rear Center */
109 RR = (1 << 7), /* Rear Right */
110 RLC = (1 << 8), /* Rear Left Center */
111 RRC = (1 << 9), /* Rear Right Center */
112 LFE = (1 << 10), /* Low Frequency Effect */
113 FLW = (1 << 11), /* Front Left Wide */
114 FRW = (1 << 12), /* Front Right Wide */
115 FLH = (1 << 13), /* Front Left High */
116 FCH = (1 << 14), /* Front Center High */
117 FRH = (1 << 15), /* Front Right High */
118 TC = (1 << 16), /* Top Center */
119};
120
121/*
122 * ELD SA bits in the CEA Speaker Allocation data block
123 */
124static int eld_speaker_allocation_bits[] = {
125 [0] = FL | FR,
126 [1] = LFE,
127 [2] = FC,
128 [3] = RL | RR,
129 [4] = RC,
130 [5] = FLC | FRC,
131 [6] = RLC | RRC,
132 /* the following are not defined in ELD yet */
133 [7] = FLW | FRW,
134 [8] = FLH | FRH,
135 [9] = TC,
136 [10] = FCH,
137};
138
139struct cea_channel_speaker_allocation {
140 int ca_index;
141 int speakers[8];
142
143 /* derived values, just for convenience */
144 int channels;
145 int spk_mask;
146};
147
148/*
149 * ALSA sequence is:
150 *
151 * surround40 surround41 surround50 surround51 surround71
152 * ch0 front left = = = =
153 * ch1 front right = = = =
154 * ch2 rear left = = = =
155 * ch3 rear right = = = =
156 * ch4 LFE center center center
157 * ch5 LFE LFE
158 * ch6 side left
159 * ch7 side right
160 *
161 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
162 */
163static int hdmi_channel_mapping[0x32][8] = {
164 /* stereo */
165 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
166 /* 2.1 */
167 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
168 /* Dolby Surround */
169 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
170 /* surround40 */
171 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
172 /* 4ch */
173 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
174 /* surround41 */
175 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
176 /* surround50 */
177 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
178 /* surround51 */
179 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
180 /* 7.1 */
181 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
182};
183
184/*
185 * This is an ordered list!
186 *
187 * The preceding ones have better chances to be selected by
188 * hdmi_setup_channel_allocation().
189 */
190static struct cea_channel_speaker_allocation channel_allocations[] = {
191/* channel: 7 6 5 4 3 2 1 0 */
192{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
193 /* 2.1 */
194{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
195 /* Dolby Surround */
196{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
197 /* surround40 */
198{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
199 /* surround41 */
200{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
201 /* surround50 */
202{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
203 /* surround51 */
204{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
205 /* 6.1 */
206{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
207 /* surround71 */
208{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
209
210{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
211{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
212{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
213{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
214{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
215{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
216{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
217{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
218{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
219{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
220{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
222{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
223{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
224{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
225{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
226{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
227{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
228{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
229{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
230{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
231{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
232{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
233{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
234{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
235{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
236{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
237{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
238{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
239{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
240{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
241{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
242{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
243{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
244{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
245{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
246{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
247{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
248{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
249{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
250{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
251};
252
253/*
254 * HDA/HDMI auto parsing
255 */
256
257static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
258{
259 int i;
260
261 for (i = 0; nids[i]; i++)
262 if (nids[i] == nid)
263 return i;
264
265 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
266 return -EINVAL;
267}
268
269static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
270{
271 struct intel_hdmi_spec *spec = codec->spec;
272 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
273 int conn_len, curr;
274 int index;
275
276 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
277 snd_printk(KERN_WARNING
278 "HDMI: pin %d wcaps %#x "
279 "does not support connection list\n",
280 pin_nid, get_wcaps(codec, pin_nid));
281 return -EINVAL;
282 }
283
284 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
285 HDA_MAX_CONNECTIONS);
286 if (conn_len > 1)
287 curr = snd_hda_codec_read(codec, pin_nid, 0,
288 AC_VERB_GET_CONNECT_SEL, 0);
289 else
290 curr = 0;
291
292 index = hda_node_index(spec->pin, pin_nid);
293 if (index < 0)
294 return -EINVAL;
295
296 spec->pin_cvt[index] = conn_list[curr];
297
298 return 0;
299}
300
301static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
302 struct hdmi_eld *eld)
303{
304 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
305 snd_hdmi_show_eld(eld);
306}
307
308static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
309 struct hdmi_eld *eld)
310{
311 int present = snd_hda_pin_sense(codec, pin_nid);
312
313 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
314 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
315
316 if (present & AC_PINSENSE_ELDV)
317 hdmi_get_show_eld(codec, pin_nid, eld);
318}
319
320static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
321{
322 struct intel_hdmi_spec *spec = codec->spec;
323
324 if (spec->num_pins >= INTEL_HDMI_PINS) {
325 snd_printk(KERN_WARNING
326 "HDMI: no space for pin %d \n", pin_nid);
327 return -EINVAL;
328 }
329
330 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
331
332 spec->pin[spec->num_pins] = pin_nid;
333 spec->num_pins++;
334
335 /*
336 * It is assumed that converter nodes come first in the node list and
337 * hence have been registered and usable now.
338 */
339 return intel_hdmi_read_pin_conn(codec, pin_nid);
340}
341
342static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
343{
344 struct intel_hdmi_spec *spec = codec->spec;
345
346 if (spec->num_cvts >= INTEL_HDMI_CVTS) {
347 snd_printk(KERN_WARNING
348 "HDMI: no space for converter %d \n", nid);
349 return -EINVAL;
350 }
351
352 spec->cvt[spec->num_cvts] = nid;
353 spec->num_cvts++;
354
355 return 0;
356}
357
358static int intel_hdmi_parse_codec(struct hda_codec *codec)
359{
360 hda_nid_t nid;
361 int i, nodes;
362
363 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
364 if (!nid || nodes < 0) {
365 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
366 return -EINVAL;
367 }
368
369 for (i = 0; i < nodes; i++, nid++) {
370 unsigned int caps;
371 unsigned int type;
372
373 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
374 type = get_wcaps_type(caps);
375
376 if (!(caps & AC_WCAP_DIGITAL))
377 continue;
378
379 switch (type) {
380 case AC_WID_AUD_OUT:
381 if (intel_hdmi_add_cvt(codec, nid) < 0)
382 return -EINVAL;
383 break;
384 case AC_WID_PIN:
385 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
386 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
387 continue;
388 if (intel_hdmi_add_pin(codec, nid) < 0)
389 return -EINVAL;
390 break;
391 }
392 }
393
394 /*
395 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
396 * can be lost and presence sense verb will become inaccurate if the
397 * HDA link is powered off at hot plug or hw initialization time.
398 */
399#ifdef CONFIG_SND_HDA_POWER_SAVE
400 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
401 AC_PWRST_EPSS))
402 codec->bus->power_keep_link_on = 1;
403#endif
404
405 return 0;
406}
407
408/*
409 * HDMI routines
410 */
411
412#ifdef BE_PARANOID
413static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
414 int *packet_index, int *byte_index)
415{
416 int val;
417
418 val = snd_hda_codec_read(codec, pin_nid, 0,
419 AC_VERB_GET_HDMI_DIP_INDEX, 0);
420
421 *packet_index = val >> 5;
422 *byte_index = val & 0x1f;
423}
424#endif
425
426static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
427 int packet_index, int byte_index)
428{
429 int val;
430
431 val = (packet_index << 5) | (byte_index & 0x1f);
432
433 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
434}
435
436static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
437 unsigned char val)
438{
439 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
440}
441
442static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
443{
444 /* Unmute */
445 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
446 snd_hda_codec_write(codec, pin_nid, 0,
447 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
448 /* Enable pin out */
449 snd_hda_codec_write(codec, pin_nid, 0,
450 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
451}
452
453/*
454 * Enable Audio InfoFrame Transmission
455 */
456static void hdmi_start_infoframe_trans(struct hda_codec *codec,
457 hda_nid_t pin_nid)
458{
459 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
460 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
461 AC_DIPXMIT_BEST);
462}
463
464/*
465 * Disable Audio InfoFrame Transmission
466 */
467static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
468 hda_nid_t pin_nid)
469{
470 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
471 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
472 AC_DIPXMIT_DISABLE);
473}
474
475static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
476{
477 return 1 + snd_hda_codec_read(codec, nid, 0,
478 AC_VERB_GET_CVT_CHAN_COUNT, 0);
479}
480
481static void hdmi_set_channel_count(struct hda_codec *codec,
482 hda_nid_t nid, int chs)
483{
484 if (chs != hdmi_get_channel_count(codec, nid))
485 snd_hda_codec_write(codec, nid, 0,
486 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
487}
488
489static void hdmi_debug_channel_mapping(struct hda_codec *codec,
490 hda_nid_t pin_nid)
491{
492#ifdef CONFIG_SND_DEBUG_VERBOSE
493 int i;
494 int slot;
495
496 for (i = 0; i < 8; i++) {
497 slot = snd_hda_codec_read(codec, pin_nid, 0,
498 AC_VERB_GET_HDMI_CHAN_SLOT, i);
499 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
500 slot >> 4, slot & 0xf);
501 }
502#endif
503}
504
505
506/*
507 * Audio InfoFrame routines
508 */
509
510static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
511{
512#ifdef CONFIG_SND_DEBUG_VERBOSE
513 int i;
514 int size;
515
516 size = snd_hdmi_get_eld_size(codec, pin_nid);
517 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
518
519 for (i = 0; i < 8; i++) {
520 size = snd_hda_codec_read(codec, pin_nid, 0,
521 AC_VERB_GET_HDMI_DIP_SIZE, i);
522 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
523 }
524#endif
525}
526
527static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
528{
529#ifdef BE_PARANOID
530 int i, j;
531 int size;
532 int pi, bi;
533 for (i = 0; i < 8; i++) {
534 size = snd_hda_codec_read(codec, pin_nid, 0,
535 AC_VERB_GET_HDMI_DIP_SIZE, i);
536 if (size == 0)
537 continue;
538
539 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
540 for (j = 1; j < 1000; j++) {
541 hdmi_write_dip_byte(codec, pin_nid, 0x0);
542 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
543 if (pi != i)
544 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
545 bi, pi, i);
546 if (bi == 0) /* byte index wrapped around */
547 break;
548 }
549 snd_printd(KERN_INFO
550 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
551 i, size, j);
552 }
553#endif
554}
555
556static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
557{
558 u8 *bytes = (u8 *)ai;
559 u8 sum = 0;
560 int i;
561
562 ai->checksum = 0;
563
564 for (i = 0; i < sizeof(*ai); i++)
565 sum += bytes[i];
566
567 ai->checksum = - sum;
568}
569
570static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
571 hda_nid_t pin_nid,
572 struct hdmi_audio_infoframe *ai)
573{
574 u8 *bytes = (u8 *)ai;
575 int i;
576
577 hdmi_debug_dip_size(codec, pin_nid);
578 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
579
580 hdmi_checksum_audio_infoframe(ai);
581
582 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
583 for (i = 0; i < sizeof(*ai); i++)
584 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
585}
586
587/*
588 * Compute derived values in channel_allocations[].
589 */
590static void init_channel_allocations(void)
591{
592 int i, j;
593 struct cea_channel_speaker_allocation *p;
594
595 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
596 p = channel_allocations + i;
597 p->channels = 0;
598 p->spk_mask = 0;
599 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
600 if (p->speakers[j]) {
601 p->channels++;
602 p->spk_mask |= p->speakers[j];
603 }
604 }
605}
606
607/*
608 * The transformation takes two steps:
609 *
610 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
611 * spk_mask => (channel_allocations[]) => ai->CA
612 *
613 * TODO: it could select the wrong CA from multiple candidates.
614*/
615static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
616 struct hdmi_audio_infoframe *ai)
617{
618 struct intel_hdmi_spec *spec = codec->spec;
619 struct hdmi_eld *eld;
620 int i;
621 int spk_mask = 0;
622 int channels = 1 + (ai->CC02_CT47 & 0x7);
623 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
624
625 /*
626 * CA defaults to 0 for basic stereo audio
627 */
628 if (channels <= 2)
629 return 0;
630
631 i = hda_node_index(spec->pin_cvt, nid);
632 if (i < 0)
633 return 0;
634 eld = &spec->sink_eld[i];
635
636 /*
637 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
638 * in console or for audio devices. Assume the highest speakers
639 * configuration, to _not_ prohibit multi-channel audio playback.
640 */
641 if (!eld->spk_alloc)
642 eld->spk_alloc = 0xffff;
643
644 /*
645 * expand ELD's speaker allocation mask
646 *
647 * ELD tells the speaker mask in a compact(paired) form,
648 * expand ELD's notions to match the ones used by Audio InfoFrame.
649 */
650 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
651 if (eld->spk_alloc & (1 << i))
652 spk_mask |= eld_speaker_allocation_bits[i];
653 }
654
655 /* search for the first working match in the CA table */
656 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
657 if (channels == channel_allocations[i].channels &&
658 (spk_mask & channel_allocations[i].spk_mask) ==
659 channel_allocations[i].spk_mask) {
660 ai->CA = channel_allocations[i].ca_index;
661 break;
662 }
663 }
664
665 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
666 snd_printdd(KERN_INFO
667 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
668 ai->CA, channels, buf);
669
670 return ai->CA;
671}
672
673static void hdmi_setup_channel_mapping(struct hda_codec *codec,
674 hda_nid_t pin_nid,
675 struct hdmi_audio_infoframe *ai)
676{
677 int i;
678 int ca = ai->CA;
679 int err;
680
681 if (hdmi_channel_mapping[ca][1] == 0) {
682 for (i = 0; i < channel_allocations[ca].channels; i++)
683 hdmi_channel_mapping[ca][i] = i | (i << 4);
684 for (; i < 8; i++)
685 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
686 }
687
688 for (i = 0; i < 8; i++) {
689 err = snd_hda_codec_write(codec, pin_nid, 0,
690 AC_VERB_SET_HDMI_CHAN_SLOT,
691 hdmi_channel_mapping[ca][i]);
692 if (err) {
693 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
694 break;
695 }
696 }
697
698 hdmi_debug_channel_mapping(codec, pin_nid);
699}
700
701static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
702 struct hdmi_audio_infoframe *ai)
703{
704 u8 *bytes = (u8 *)ai;
705 u8 val;
706 int i;
707
708 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
709 != AC_DIPXMIT_BEST)
710 return false;
711
712 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
713 for (i = 0; i < sizeof(*ai); i++) {
714 val = snd_hda_codec_read(codec, pin_nid, 0,
715 AC_VERB_GET_HDMI_DIP_DATA, 0);
716 if (val != bytes[i])
717 return false;
718 }
719
720 return true;
721}
722
723static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
724 struct snd_pcm_substream *substream)
725{
726 struct intel_hdmi_spec *spec = codec->spec;
727 hda_nid_t pin_nid;
728 int i;
729 struct hdmi_audio_infoframe ai = {
730 .type = 0x84,
731 .ver = 0x01,
732 .len = 0x0a,
733 .CC02_CT47 = substream->runtime->channels - 1,
734 };
735
736 hdmi_setup_channel_allocation(codec, nid, &ai);
737
738 for (i = 0; i < spec->num_pins; i++) {
739 if (spec->pin_cvt[i] != nid)
740 continue;
741 if (!spec->sink_eld[i].monitor_present)
742 continue;
743
744 pin_nid = spec->pin[i];
745 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
746 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
747 hdmi_stop_infoframe_trans(codec, pin_nid);
748 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
749 hdmi_start_infoframe_trans(codec, pin_nid);
750 }
751 }
752}
753
754
755/* 53/*
756 * Unsolicited events 54 * HDMI callbacks
757 */ 55 */
758 56
759static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
760{
761 struct intel_hdmi_spec *spec = codec->spec;
762 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
763 int pind = !!(res & AC_UNSOL_RES_PD);
764 int eldv = !!(res & AC_UNSOL_RES_ELDV);
765 int index;
766
767 printk(KERN_INFO
768 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
769 tag, pind, eldv);
770
771 index = hda_node_index(spec->pin, tag);
772 if (index < 0)
773 return;
774
775 spec->sink_eld[index].monitor_present = pind;
776 spec->sink_eld[index].eld_valid = eldv;
777
778 if (pind && eldv) {
779 hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
780 /* TODO: do real things about ELD */
781 }
782}
783
784static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
785{
786 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
787 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
788 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
789 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
790
791 printk(KERN_INFO
792 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
793 tag,
794 subtag,
795 cp_state,
796 cp_ready);
797
798 /* TODO */
799 if (cp_state)
800 ;
801 if (cp_ready)
802 ;
803}
804
805
806static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
807{
808 struct intel_hdmi_spec *spec = codec->spec;
809 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
810 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
811
812 if (hda_node_index(spec->pin, tag) < 0) {
813 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
814 return;
815 }
816
817 if (subtag == 0)
818 hdmi_intrinsic_event(codec, res);
819 else
820 hdmi_non_intrinsic_event(codec, res);
821}
822
823/*
824 * Callbacks
825 */
826
827static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
828 u32 stream_tag, int format)
829{
830 int tag;
831 int fmt;
832
833 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
834 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
835
836 snd_printdd("hdmi_setup_stream: "
837 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
838 nid,
839 tag == stream_tag ? "" : "new-",
840 stream_tag,
841 fmt == format ? "" : "new-",
842 format);
843
844 if (tag != stream_tag)
845 snd_hda_codec_write(codec, nid, 0,
846 AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
847 if (fmt != format)
848 snd_hda_codec_write(codec, nid, 0,
849 AC_VERB_SET_STREAM_FORMAT, format);
850}
851
852static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 57static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
853 struct hda_codec *codec, 58 struct hda_codec *codec,
854 unsigned int stream_tag, 59 unsigned int stream_tag,
@@ -882,7 +87,7 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
882 87
883static int intel_hdmi_build_pcms(struct hda_codec *codec) 88static int intel_hdmi_build_pcms(struct hda_codec *codec)
884{ 89{
885 struct intel_hdmi_spec *spec = codec->spec; 90 struct hdmi_spec *spec = codec->spec;
886 struct hda_pcm *info = spec->pcm_rec; 91 struct hda_pcm *info = spec->pcm_rec;
887 int i; 92 int i;
888 93
@@ -908,7 +113,7 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
908 113
909static int intel_hdmi_build_controls(struct hda_codec *codec) 114static int intel_hdmi_build_controls(struct hda_codec *codec)
910{ 115{
911 struct intel_hdmi_spec *spec = codec->spec; 116 struct hdmi_spec *spec = codec->spec;
912 int err; 117 int err;
913 int i; 118 int i;
914 119
@@ -923,7 +128,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec)
923 128
924static int intel_hdmi_init(struct hda_codec *codec) 129static int intel_hdmi_init(struct hda_codec *codec)
925{ 130{
926 struct intel_hdmi_spec *spec = codec->spec; 131 struct hdmi_spec *spec = codec->spec;
927 int i; 132 int i;
928 133
929 for (i = 0; spec->pin[i]; i++) { 134 for (i = 0; spec->pin[i]; i++) {
@@ -937,7 +142,7 @@ static int intel_hdmi_init(struct hda_codec *codec)
937 142
938static void intel_hdmi_free(struct hda_codec *codec) 143static void intel_hdmi_free(struct hda_codec *codec)
939{ 144{
940 struct intel_hdmi_spec *spec = codec->spec; 145 struct hdmi_spec *spec = codec->spec;
941 int i; 146 int i;
942 147
943 for (i = 0; i < spec->num_pins; i++) 148 for (i = 0; i < spec->num_pins; i++)
@@ -951,12 +156,12 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
951 .free = intel_hdmi_free, 156 .free = intel_hdmi_free,
952 .build_pcms = intel_hdmi_build_pcms, 157 .build_pcms = intel_hdmi_build_pcms,
953 .build_controls = intel_hdmi_build_controls, 158 .build_controls = intel_hdmi_build_controls,
954 .unsol_event = intel_hdmi_unsol_event, 159 .unsol_event = hdmi_unsol_event,
955}; 160};
956 161
957static int patch_intel_hdmi(struct hda_codec *codec) 162static int patch_intel_hdmi(struct hda_codec *codec)
958{ 163{
959 struct intel_hdmi_spec *spec; 164 struct hdmi_spec *spec;
960 int i; 165 int i;
961 166
962 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -964,7 +169,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
964 return -ENOMEM; 169 return -ENOMEM;
965 170
966 codec->spec = spec; 171 codec->spec = spec;
967 if (intel_hdmi_parse_codec(codec) < 0) { 172 if (hdmi_parse_codec(codec) < 0) {
968 codec->spec = NULL; 173 codec->spec = NULL;
969 kfree(spec); 174 kfree(spec);
970 return -EINVAL; 175 return -EINVAL;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 6afdab09bab7..70669a246902 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,13 +29,23 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
32/* define below to restrict the supported rates and formats */ 41/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */ 42/* #define LIMITED_RATE_FMT_SUPPORT */
34 43
35struct nvhdmi_spec { 44enum HDACodec {
36 struct hda_multi_out multiout; 45 HDA_CODEC_NVIDIA_MCP7X,
37 46 HDA_CODEC_NVIDIA_MCP89,
38 struct hda_pcm pcm_rec; 47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
39}; 49};
40 50
41#define Nv_VERB_SET_Channel_Allocation 0xF79 51#define Nv_VERB_SET_Channel_Allocation 0xF79
@@ -43,15 +53,18 @@ struct nvhdmi_spec {
43#define Nv_VERB_SET_Audio_Protection_On 0xF98 53#define Nv_VERB_SET_Audio_Protection_On 0xF98
44#define Nv_VERB_SET_Audio_Protection_Off 0xF99 54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
45 55
46#define Nv_Master_Convert_nid 0x04 56#define nvhdmi_master_con_nid_7x 0x04
47#define Nv_Master_Pin_nid 0x05 57#define nvhdmi_master_pin_nid_7x 0x05
48 58
49static hda_nid_t nvhdmi_convert_nids[4] = { 59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
50 /*front, rear, clfe, rear_surr */ 63 /*front, rear, clfe, rear_surr */
51 0x6, 0x8, 0xa, 0xc, 64 0x6, 0x8, 0xa, 0xc,
52}; 65};
53 66
54static struct hda_verb nvhdmi_basic_init[] = { 67static struct hda_verb nvhdmi_basic_init_7x[] = {
55 /* set audio protect on */ 68 /* set audio protect on */
56 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
57 /* enable digital output on pin widget */ 70 /* enable digital output on pin widget */
@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
84 */ 97 */
85static int nvhdmi_build_controls(struct hda_codec *codec) 98static int nvhdmi_build_controls(struct hda_codec *codec)
86{ 99{
87 struct nvhdmi_spec *spec = codec->spec; 100 struct hdmi_spec *spec = codec->spec;
88 int err; 101 int err;
102 int i;
89 103
90 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
91 if (err < 0) 105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
92 return err; 106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
93 118
94 return 0; 119 return 0;
95} 120}
96 121
97static int nvhdmi_init(struct hda_codec *codec) 122static int nvhdmi_init(struct hda_codec *codec)
98{ 123{
99 snd_hda_sequence_write(codec, nvhdmi_basic_init); 124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
100 return 0; 137 return 0;
101} 138}
102 139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
103/* 154/*
104 * Digital out 155 * Digital out
105 */ 156 */
@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
107 struct hda_codec *codec, 158 struct hda_codec *codec,
108 struct snd_pcm_substream *substream) 159 struct snd_pcm_substream *substream)
109{ 160{
110 struct nvhdmi_spec *spec = codec->spec; 161 struct hdmi_spec *spec = codec->spec;
111 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
112} 163}
113 164
114static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, 165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
115 struct hda_codec *codec, 166 struct hda_codec *codec,
116 struct snd_pcm_substream *substream) 167 struct snd_pcm_substream *substream)
117{ 168{
118 struct nvhdmi_spec *spec = codec->spec; 169 struct hdmi_spec *spec = codec->spec;
119 int i; 170 int i;
120 171
121 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
122 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
123 for (i = 0; i < 4; i++) { 174 for (i = 0; i < 4; i++) {
124 /* set the stream id */ 175 /* set the stream id */
125 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
126 AC_VERB_SET_CHANNEL_STREAMID, 0); 177 AC_VERB_SET_CHANNEL_STREAMID, 0);
127 /* set the stream format */ 178 /* set the stream format */
128 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
129 AC_VERB_SET_STREAM_FORMAT, 0); 180 AC_VERB_SET_STREAM_FORMAT, 0);
130 } 181 }
131 182
@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
136 struct hda_codec *codec, 187 struct hda_codec *codec,
137 struct snd_pcm_substream *substream) 188 struct snd_pcm_substream *substream)
138{ 189{
139 struct nvhdmi_spec *spec = codec->spec; 190 struct hdmi_spec *spec = codec->spec;
140 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
141} 192}
142 193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206 return 0;
207}
208
143static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, 209static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
144 struct hda_codec *codec, 210 struct hda_codec *codec,
145 unsigned int stream_tag, 211 unsigned int stream_tag,
@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
181 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 247 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
182 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 248 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
183 snd_hda_codec_write(codec, 249 snd_hda_codec_write(codec,
184 Nv_Master_Convert_nid, 250 nvhdmi_master_con_nid_7x,
185 0, 251 0,
186 AC_VERB_SET_DIGI_CONVERT_1, 252 AC_VERB_SET_DIGI_CONVERT_1,
187 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 253 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
188 254
189 /* set the stream id */ 255 /* set the stream id */
190 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 256 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
191 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 257 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
192 258
193 /* set the stream format */ 259 /* set the stream format */
194 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 260 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
195 AC_VERB_SET_STREAM_FORMAT, format); 261 AC_VERB_SET_STREAM_FORMAT, format);
196 262
197 /* turn on again (if needed) */ 263 /* turn on again (if needed) */
198 /* enable and set the channel status audio/data flag */ 264 /* enable and set the channel status audio/data flag */
199 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 265 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
200 snd_hda_codec_write(codec, 266 snd_hda_codec_write(codec,
201 Nv_Master_Convert_nid, 267 nvhdmi_master_con_nid_7x,
202 0, 268 0,
203 AC_VERB_SET_DIGI_CONVERT_1, 269 AC_VERB_SET_DIGI_CONVERT_1,
204 codec->spdif_ctls & 0xff); 270 codec->spdif_ctls & 0xff);
205 snd_hda_codec_write(codec, 271 snd_hda_codec_write(codec,
206 Nv_Master_Convert_nid, 272 nvhdmi_master_con_nid_7x,
207 0, 273 0,
208 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 274 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
209 } 275 }
@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
220 if (codec->spdif_status_reset && 286 if (codec->spdif_status_reset &&
221 (codec->spdif_ctls & AC_DIG1_ENABLE)) 287 (codec->spdif_ctls & AC_DIG1_ENABLE))
222 snd_hda_codec_write(codec, 288 snd_hda_codec_write(codec,
223 nvhdmi_convert_nids[i], 289 nvhdmi_con_nids_7x[i],
224 0, 290 0,
225 AC_VERB_SET_DIGI_CONVERT_1, 291 AC_VERB_SET_DIGI_CONVERT_1,
226 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 292 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
227 /* set the stream id */ 293 /* set the stream id */
228 snd_hda_codec_write(codec, 294 snd_hda_codec_write(codec,
229 nvhdmi_convert_nids[i], 295 nvhdmi_con_nids_7x[i],
230 0, 296 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 297 AC_VERB_SET_CHANNEL_STREAMID,
232 (stream_tag << 4) | channel_id); 298 (stream_tag << 4) | channel_id);
233 /* set the stream format */ 299 /* set the stream format */
234 snd_hda_codec_write(codec, 300 snd_hda_codec_write(codec,
235 nvhdmi_convert_nids[i], 301 nvhdmi_con_nids_7x[i],
236 0, 302 0,
237 AC_VERB_SET_STREAM_FORMAT, 303 AC_VERB_SET_STREAM_FORMAT,
238 format); 304 format);
@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
241 if (codec->spdif_status_reset && 307 if (codec->spdif_status_reset &&
242 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 308 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
243 snd_hda_codec_write(codec, 309 snd_hda_codec_write(codec,
244 nvhdmi_convert_nids[i], 310 nvhdmi_con_nids_7x[i],
245 0, 311 0,
246 AC_VERB_SET_DIGI_CONVERT_1, 312 AC_VERB_SET_DIGI_CONVERT_1,
247 codec->spdif_ctls & 0xff); 313 codec->spdif_ctls & 0xff);
248 snd_hda_codec_write(codec, 314 snd_hda_codec_write(codec,
249 nvhdmi_convert_nids[i], 315 nvhdmi_con_nids_7x[i],
250 0, 316 0,
251 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 317 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
252 } 318 }
@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
261 return 0; 327 return 0;
262} 328}
263 329
330static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 struct hda_codec *codec,
332 struct snd_pcm_substream *substream)
333{
334 return 0;
335}
336
264static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, 337static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
265 struct hda_codec *codec, 338 struct hda_codec *codec,
266 unsigned int stream_tag, 339 unsigned int stream_tag,
267 unsigned int format, 340 unsigned int format,
268 struct snd_pcm_substream *substream) 341 struct snd_pcm_substream *substream)
269{ 342{
270 struct nvhdmi_spec *spec = codec->spec; 343 struct hdmi_spec *spec = codec->spec;
271 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
272 format, substream); 345 format, substream);
273} 346}
274 347
275static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { 348static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
349 .substreams = 1,
350 .channels_min = 2,
351 .rates = SUPPORTED_RATES,
352 .maxbps = SUPPORTED_MAXBPS,
353 .formats = SUPPORTED_FORMATS,
354 .ops = {
355 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
356 .cleanup = nvhdmi_playback_pcm_cleanup,
357 },
358};
359
360static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
276 .substreams = 1, 361 .substreams = 1,
277 .channels_min = 2, 362 .channels_min = 2,
278 .channels_max = 8, 363 .channels_max = 8,
279 .nid = Nv_Master_Convert_nid, 364 .nid = nvhdmi_master_con_nid_7x,
280 .rates = SUPPORTED_RATES, 365 .rates = SUPPORTED_RATES,
281 .maxbps = SUPPORTED_MAXBPS, 366 .maxbps = SUPPORTED_MAXBPS,
282 .formats = SUPPORTED_FORMATS, 367 .formats = SUPPORTED_FORMATS,
283 .ops = { 368 .ops = {
284 .open = nvhdmi_dig_playback_pcm_open, 369 .open = nvhdmi_dig_playback_pcm_open,
285 .close = nvhdmi_dig_playback_pcm_close_8ch, 370 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
286 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch 371 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
287 }, 372 },
288}; 373};
@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
291 .substreams = 1, 376 .substreams = 1,
292 .channels_min = 2, 377 .channels_min = 2,
293 .channels_max = 2, 378 .channels_max = 2,
294 .nid = Nv_Master_Convert_nid, 379 .nid = nvhdmi_master_con_nid_7x,
295 .rates = SUPPORTED_RATES, 380 .rates = SUPPORTED_RATES,
296 .maxbps = SUPPORTED_MAXBPS, 381 .maxbps = SUPPORTED_MAXBPS,
297 .formats = SUPPORTED_FORMATS, 382 .formats = SUPPORTED_FORMATS,
@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
302 }, 387 },
303}; 388};
304 389
305static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) 390static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
391{
392 struct hdmi_spec *spec = codec->spec;
393 struct hda_pcm *info = spec->pcm_rec;
394 int i;
395
396 codec->num_pcms = spec->num_cvts;
397 codec->pcm_info = info;
398
399 for (i = 0; i < codec->num_pcms; i++, info++) {
400 unsigned int chans;
401
402 chans = get_wcaps(codec, spec->cvt[i]);
403 chans = get_wcaps_channels(chans);
404
405 info->name = nvhdmi_pcm_names[i];
406 info->pcm_type = HDA_PCM_TYPE_HDMI;
407 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
408 = nvhdmi_pcm_digital_playback_8ch_89;
409 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
410 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
411 }
412
413 return 0;
414}
415
416static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
306{ 417{
307 struct nvhdmi_spec *spec = codec->spec; 418 struct hdmi_spec *spec = codec->spec;
308 struct hda_pcm *info = &spec->pcm_rec; 419 struct hda_pcm *info = spec->pcm_rec;
309 420
310 codec->num_pcms = 1; 421 codec->num_pcms = 1;
311 codec->pcm_info = info; 422 codec->pcm_info = info;
@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
313 info->name = "NVIDIA HDMI"; 424 info->name = "NVIDIA HDMI";
314 info->pcm_type = HDA_PCM_TYPE_HDMI; 425 info->pcm_type = HDA_PCM_TYPE_HDMI;
315 info->stream[SNDRV_PCM_STREAM_PLAYBACK] 426 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
316 = nvhdmi_pcm_digital_playback_8ch; 427 = nvhdmi_pcm_digital_playback_8ch_7x;
317 428
318 return 0; 429 return 0;
319} 430}
320 431
321static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) 432static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
322{ 433{
323 struct nvhdmi_spec *spec = codec->spec; 434 struct hdmi_spec *spec = codec->spec;
324 struct hda_pcm *info = &spec->pcm_rec; 435 struct hda_pcm *info = spec->pcm_rec;
325 436
326 codec->num_pcms = 1; 437 codec->num_pcms = 1;
327 codec->pcm_info = info; 438 codec->pcm_info = info;
@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
334 return 0; 445 return 0;
335} 446}
336 447
337static void nvhdmi_free(struct hda_codec *codec) 448static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
338{ 449 .build_controls = nvhdmi_build_controls,
339 kfree(codec->spec); 450 .build_pcms = nvhdmi_build_pcms_8ch_89,
340} 451 .init = nvhdmi_init,
452 .free = nvhdmi_free,
453 .unsol_event = hdmi_unsol_event,
454};
341 455
342static struct hda_codec_ops nvhdmi_patch_ops_8ch = { 456static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
343 .build_controls = nvhdmi_build_controls, 457 .build_controls = nvhdmi_build_controls,
344 .build_pcms = nvhdmi_build_pcms_8ch, 458 .build_pcms = nvhdmi_build_pcms_8ch_7x,
345 .init = nvhdmi_init, 459 .init = nvhdmi_init,
346 .free = nvhdmi_free, 460 .free = nvhdmi_free,
347}; 461};
@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
353 .free = nvhdmi_free, 467 .free = nvhdmi_free,
354}; 468};
355 469
356static int patch_nvhdmi_8ch(struct hda_codec *codec) 470static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
471{
472 struct hdmi_spec *spec;
473 int i;
474
475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
476 if (spec == NULL)
477 return -ENOMEM;
478
479 codec->spec = spec;
480 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
481
482 if (hdmi_parse_codec(codec) < 0) {
483 codec->spec = NULL;
484 kfree(spec);
485 return -EINVAL;
486 }
487 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
488
489 for (i = 0; i < spec->num_pins; i++)
490 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
491
492 init_channel_allocations();
493
494 return 0;
495}
496
497static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
357{ 498{
358 struct nvhdmi_spec *spec; 499 struct hdmi_spec *spec;
359 500
360 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
361 if (spec == NULL) 502 if (spec == NULL)
@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
365 506
366 spec->multiout.num_dacs = 0; /* no analog */ 507 spec->multiout.num_dacs = 0; /* no analog */
367 spec->multiout.max_channels = 8; 508 spec->multiout.max_channels = 8;
368 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 509 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
510 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
369 511
370 codec->patch_ops = nvhdmi_patch_ops_8ch; 512 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
371 513
372 return 0; 514 return 0;
373} 515}
374 516
375static int patch_nvhdmi_2ch(struct hda_codec *codec) 517static int patch_nvhdmi_2ch(struct hda_codec *codec)
376{ 518{
377 struct nvhdmi_spec *spec; 519 struct hdmi_spec *spec;
378 520
379 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 521 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
380 if (spec == NULL) 522 if (spec == NULL)
@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
384 526
385 spec->multiout.num_dacs = 0; /* no analog */ 527 spec->multiout.num_dacs = 0; /* no analog */
386 spec->multiout.max_channels = 2; 528 spec->multiout.max_channels = 2;
387 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 529 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
530 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
388 531
389 codec->patch_ops = nvhdmi_patch_ops_2ch; 532 codec->patch_ops = nvhdmi_patch_ops_2ch;
390 533
@@ -395,13 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
395 * patch entries 538 * patch entries
396 */ 539 */
397static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
398 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
399 { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
400 { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
401 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
402 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
403 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 541 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
404 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 542 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
543 { .id = 0x10de0002, .name = "MCP77/78 HDMI",
544 .patch = patch_nvhdmi_8ch_7x },
545 { .id = 0x10de0003, .name = "MCP77/78 HDMI",
546 .patch = patch_nvhdmi_8ch_7x },
547 { .id = 0x10de0005, .name = "MCP77/78 HDMI",
548 .patch = patch_nvhdmi_8ch_7x },
549 { .id = 0x10de0006, .name = "MCP77/78 HDMI",
550 .patch = patch_nvhdmi_8ch_7x },
551 { .id = 0x10de0007, .name = "MCP79/7A HDMI",
552 .patch = patch_nvhdmi_8ch_7x },
553 { .id = 0x10de000c, .name = "MCP89 HDMI",
554 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000b, .name = "GT21x HDMI",
556 .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de000d, .name = "GT240 HDMI",
558 .patch = patch_nvhdmi_8ch_89 },
405 {} /* terminator */ 559 {} /* terminator */
406}; 560};
407 561
@@ -412,9 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0006");
412MODULE_ALIAS("snd-hda-codec-id:10de0007"); 566MODULE_ALIAS("snd-hda-codec-id:10de0007");
413MODULE_ALIAS("snd-hda-codec-id:10de0067"); 567MODULE_ALIAS("snd-hda-codec-id:10de0067");
414MODULE_ALIAS("snd-hda-codec-id:10de8001"); 568MODULE_ALIAS("snd-hda-codec-id:10de8001");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000b");
571MODULE_ALIAS("snd-hda-codec-id:10de000d");
415 572
416MODULE_LICENSE("GPL"); 573MODULE_LICENSE("GPL");
417MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); 574MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
418 575
419static struct hda_codec_preset_list nvhdmi_list = { 576static struct hda_codec_preset_list nvhdmi_list = {
420 .preset = snd_hda_preset_nvhdmi, 577 .preset = snd_hda_preset_nvhdmi,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e8cbe216e912..5d2fbb87b871 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4915,7 +4915,7 @@ static void fixup_automic_adc(struct hda_codec *codec)
4915static void fixup_single_adc(struct hda_codec *codec) 4915static void fixup_single_adc(struct hda_codec *codec)
4916{ 4916{
4917 struct alc_spec *spec = codec->spec; 4917 struct alc_spec *spec = codec->spec;
4918 hda_nid_t pin; 4918 hda_nid_t pin = 0;
4919 int i; 4919 int i;
4920 4920
4921 /* search for the input pin; there must be only one */ 4921 /* search for the input pin; there must be only one */
@@ -13561,6 +13561,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13561static void alc269_quanta_fl1_setup(struct hda_codec *codec) 13561static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13562{ 13562{
13563 struct alc_spec *spec = codec->spec; 13563 struct alc_spec *spec = codec->spec;
13564 spec->autocfg.hp_pins[0] = 0x15;
13565 spec->autocfg.speaker_pins[0] = 0x14;
13564 spec->ext_mic.pin = 0x18; 13566 spec->ext_mic.pin = 0x18;
13565 spec->ext_mic.mux_idx = 0; 13567 spec->ext_mic.mux_idx = 0;
13566 spec->int_mic.pin = 0x19; 13568 spec->int_mic.pin = 0x19;
@@ -13656,6 +13658,8 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
13656static void alc269_laptop_dmic_setup(struct hda_codec *codec) 13658static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13657{ 13659{
13658 struct alc_spec *spec = codec->spec; 13660 struct alc_spec *spec = codec->spec;
13661 spec->autocfg.hp_pins[0] = 0x15;
13662 spec->autocfg.speaker_pins[0] = 0x14;
13659 spec->ext_mic.pin = 0x18; 13663 spec->ext_mic.pin = 0x18;
13660 spec->ext_mic.mux_idx = 0; 13664 spec->ext_mic.mux_idx = 0;
13661 spec->int_mic.pin = 0x12; 13665 spec->int_mic.pin = 0x12;
@@ -13666,6 +13670,8 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13666static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) 13670static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13667{ 13671{
13668 struct alc_spec *spec = codec->spec; 13672 struct alc_spec *spec = codec->spec;
13673 spec->autocfg.hp_pins[0] = 0x15;
13674 spec->autocfg.speaker_pins[0] = 0x14;
13669 spec->ext_mic.pin = 0x18; 13675 spec->ext_mic.pin = 0x18;
13670 spec->ext_mic.mux_idx = 0; 13676 spec->ext_mic.mux_idx = 0;
13671 spec->int_mic.pin = 0x12; 13677 spec->int_mic.pin = 0x12;
@@ -13676,6 +13682,8 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13676static void alc269_laptop_amic_setup(struct hda_codec *codec) 13682static void alc269_laptop_amic_setup(struct hda_codec *codec)
13677{ 13683{
13678 struct alc_spec *spec = codec->spec; 13684 struct alc_spec *spec = codec->spec;
13685 spec->autocfg.hp_pins[0] = 0x15;
13686 spec->autocfg.speaker_pins[0] = 0x14;
13679 spec->ext_mic.pin = 0x18; 13687 spec->ext_mic.pin = 0x18;
13680 spec->ext_mic.mux_idx = 0; 13688 spec->ext_mic.mux_idx = 0;
13681 spec->int_mic.pin = 0x19; 13689 spec->int_mic.pin = 0x19;
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 7754db166d9e..dbc4b89d74e4 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -68,7 +68,7 @@ static void wm8776_write(struct oxygen *chip,
68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 68 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
69 (reg << 9) | value); 69 (reg << 9) | value);
70 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 70 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
71 if (reg >= WM8776_HPLVOL || reg <= WM8776_DACMASTER) 71 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
72 value &= ~WM8776_UPDATE; 72 value &= ~WM8776_UPDATE;
73 data->wm8776_regs[reg] = value; 73 data->wm8776_regs[reg] = value;
74 } 74 }
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 960a227eb653..ad4462677615 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1974,9 +1974,9 @@ snd_riptide_proc_read(struct snd_info_entry *entry,
1974 } 1974 }
1975 snd_iprintf(buffer, "Paths:\n"); 1975 snd_iprintf(buffer, "Paths:\n");
1976 i = getpaths(cif, p); 1976 i = getpaths(cif, p);
1977 while (i--) { 1977 while (i >= 2) {
1978 snd_iprintf(buffer, "%x->%x ", p[i - 1], p[i]); 1978 i -= 2;
1979 i--; 1979 snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
1980 } 1980 }
1981 snd_iprintf(buffer, "\n"); 1981 snd_iprintf(buffer, "\n");
1982} 1982}
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index b9ef7e45891d..b68d99fb6af0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -90,12 +90,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (reg >= codec->reg_cache_size) 90 if (reg >= codec->reg_cache_size)
91 return -EINVAL; 91 return -EINVAL;
92 92
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */ 93 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) { 94 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value }; 95 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
96
99 if (spi_write(spi, tmp, sizeof(tmp))) { 97 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n"); 98 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO; 99 return -EIO;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a03bac943aaf..c8b0556ef431 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -427,24 +427,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
427 if (!runtime->hw.rates) { 427 if (!runtime->hw.rates) {
428 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", 428 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
429 codec_dai->name, cpu_dai->name); 429 codec_dai->name, cpu_dai->name);
430 goto machine_err; 430 goto config_err;
431 } 431 }
432 if (!runtime->hw.formats) { 432 if (!runtime->hw.formats) {
433 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", 433 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
434 codec_dai->name, cpu_dai->name); 434 codec_dai->name, cpu_dai->name);
435 goto machine_err; 435 goto config_err;
436 } 436 }
437 if (!runtime->hw.channels_min || !runtime->hw.channels_max) { 437 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
438 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 438 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
439 codec_dai->name, cpu_dai->name); 439 codec_dai->name, cpu_dai->name);
440 goto machine_err; 440 goto config_err;
441 } 441 }
442 442
443 /* Symmetry only applies if we've already got an active stream. */ 443 /* Symmetry only applies if we've already got an active stream. */
444 if (cpu_dai->active || codec_dai->active) { 444 if (cpu_dai->active || codec_dai->active) {
445 ret = soc_pcm_apply_symmetry(substream); 445 ret = soc_pcm_apply_symmetry(substream);
446 if (ret != 0) 446 if (ret != 0)
447 goto machine_err; 447 goto config_err;
448 } 448 }
449 449
450 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 450 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -464,10 +464,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
464 mutex_unlock(&pcm_mutex); 464 mutex_unlock(&pcm_mutex);
465 return 0; 465 return 0;
466 466
467machine_err: 467config_err:
468 if (machine->ops && machine->ops->shutdown) 468 if (machine->ops && machine->ops->shutdown)
469 machine->ops->shutdown(substream); 469 machine->ops->shutdown(substream);
470 470
471machine_err:
472 if (codec_dai->ops->shutdown)
473 codec_dai->ops->shutdown(substream, codec_dai);
474
471codec_dai_err: 475codec_dai_err:
472 if (platform->pcm_ops->close) 476 if (platform->pcm_ops->close)
473 platform->pcm_ops->close(substream); 477 platform->pcm_ops->close(substream);
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 8c2925814ce4..c570ae3e6d55 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -22,13 +22,13 @@ config SND_USB_AUDIO
22 will be called snd-usb-audio. 22 will be called snd-usb-audio.
23 23
24config SND_USB_UA101 24config SND_USB_UA101
25 tristate "Edirol UA-101 driver (EXPERIMENTAL)" 25 tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)"
26 depends on EXPERIMENTAL 26 depends on EXPERIMENTAL
27 select SND_PCM 27 select SND_PCM
28 select SND_RAWMIDI 28 select SND_RAWMIDI
29 help 29 help
30 Say Y here to include support for the Edirol UA-101 audio/MIDI 30 Say Y here to include support for the Edirol UA-101 and UA-1000
31 interface. 31 audio/MIDI interfaces.
32 32
33 To compile this driver as a module, choose M here: the module 33 To compile this driver as a module, choose M here: the module
34 will be called snd-ua101. 34 will be called snd-ua101.
diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h
index 9d16db027fc3..380f984babc9 100644
--- a/sound/usb/caiaq/midi.h
+++ b/sound/usb/caiaq/midi.h
@@ -3,6 +3,6 @@
3 3
4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); 4int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); 5void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
6void snd_usb_caiaq_midi_output_done(struct urb* urb); 6void snd_usb_caiaq_midi_output_done(struct urb *urb);
7 7
8#endif /* CAIAQ_MIDI_H */ 8#endif /* CAIAQ_MIDI_H */
diff --git a/sound/usb/ua101.c b/sound/usb/ua101.c
index 4f4ccdf70dd0..3d458d3b9962 100644
--- a/sound/usb/ua101.c
+++ b/sound/usb/ua101.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Edirol UA-101 driver 2 * Edirol UA-101/UA-1000 driver
3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 3 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
4 * 4 *
5 * This driver is free software: you can redistribute it and/or modify 5 * This driver is free software: you can redistribute it and/or modify
@@ -25,13 +25,10 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include "usbaudio.h" 26#include "usbaudio.h"
27 27
28MODULE_DESCRIPTION("Edirol UA-101 driver"); 28MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 29MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
30MODULE_LICENSE("GPL v2"); 30MODULE_LICENSE("GPL v2");
31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101}}"); 31MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
32
33/* I use my UA-1A for testing because I don't have a UA-101 ... */
34#define UA1A_HACK
35 32
36/* 33/*
37 * Should not be lower than the minimum scheduling delay of the host 34 * Should not be lower than the minimum scheduling delay of the host
@@ -132,9 +129,6 @@ struct ua101 {
132 dma_addr_t dma; 129 dma_addr_t dma;
133 } buffers[MAX_MEMORY_BUFFERS]; 130 } buffers[MAX_MEMORY_BUFFERS];
134 } capture, playback; 131 } capture, playback;
135
136 unsigned int fps[10];
137 unsigned int frame_counter;
138}; 132};
139 133
140static DEFINE_MUTEX(devices_mutex); 134static DEFINE_MUTEX(devices_mutex);
@@ -424,16 +418,6 @@ static void capture_urb_complete(struct urb *urb)
424 if (do_period_elapsed) 418 if (do_period_elapsed)
425 snd_pcm_period_elapsed(stream->substream); 419 snd_pcm_period_elapsed(stream->substream);
426 420
427 /* for debugging: measure the sample rate relative to the USB clock */
428 ua->fps[ua->frame_counter++ / ua->packets_per_second] += frames;
429 if (ua->frame_counter >= ARRAY_SIZE(ua->fps) * ua->packets_per_second) {
430 printk(KERN_DEBUG "capture rate:");
431 for (frames = 0; frames < ARRAY_SIZE(ua->fps); ++frames)
432 printk(KERN_CONT " %u", ua->fps[frames]);
433 printk(KERN_CONT "\n");
434 memset(ua->fps, 0, sizeof(ua->fps));
435 ua->frame_counter = 0;
436 }
437 return; 421 return;
438 422
439stream_stopped: 423stream_stopped:
@@ -1200,13 +1184,30 @@ static int ua101_probe(struct usb_interface *interface,
1200 .type = QUIRK_MIDI_FIXED_ENDPOINT, 1184 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1201 .data = &midi_ep 1185 .data = &midi_ep
1202 }; 1186 };
1187 static const int intf_numbers[2][3] = {
1188 { /* UA-101 */
1189 [INTF_PLAYBACK] = 0,
1190 [INTF_CAPTURE] = 1,
1191 [INTF_MIDI] = 2,
1192 },
1193 { /* UA-1000 */
1194 [INTF_CAPTURE] = 1,
1195 [INTF_PLAYBACK] = 2,
1196 [INTF_MIDI] = 3,
1197 },
1198 };
1203 struct snd_card *card; 1199 struct snd_card *card;
1204 struct ua101 *ua; 1200 struct ua101 *ua;
1205 unsigned int card_index, i; 1201 unsigned int card_index, i;
1202 int is_ua1000;
1203 const char *name;
1206 char usb_path[32]; 1204 char usb_path[32];
1207 int err; 1205 int err;
1208 1206
1209 if (interface->altsetting->desc.bInterfaceNumber != 0) 1207 is_ua1000 = usb_id->idProduct == 0x0044;
1208
1209 if (interface->altsetting->desc.bInterfaceNumber !=
1210 intf_numbers[is_ua1000][0])
1210 return -ENODEV; 1211 return -ENODEV;
1211 1212
1212 mutex_lock(&devices_mutex); 1213 mutex_lock(&devices_mutex);
@@ -1239,20 +1240,13 @@ static int ua101_probe(struct usb_interface *interface,
1239 init_waitqueue_head(&ua->rate_feedback_wait); 1240 init_waitqueue_head(&ua->rate_feedback_wait);
1240 init_waitqueue_head(&ua->alsa_playback_wait); 1241 init_waitqueue_head(&ua->alsa_playback_wait);
1241 1242
1242#ifdef UA1A_HACK
1243 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1244 ua->intf[2] = interface;
1245 ua->intf[0] = usb_ifnum_to_if(ua->dev, 1);
1246 ua->intf[1] = usb_ifnum_to_if(ua->dev, 2);
1247 usb_driver_claim_interface(&ua101_driver, ua->intf[0], ua);
1248 usb_driver_claim_interface(&ua101_driver, ua->intf[1], ua);
1249 } else {
1250#endif
1251 ua->intf[0] = interface; 1243 ua->intf[0] = interface;
1252 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) { 1244 for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
1253 ua->intf[i] = usb_ifnum_to_if(ua->dev, i); 1245 ua->intf[i] = usb_ifnum_to_if(ua->dev,
1246 intf_numbers[is_ua1000][i]);
1254 if (!ua->intf[i]) { 1247 if (!ua->intf[i]) {
1255 dev_err(&ua->dev->dev, "interface %u not found\n", i); 1248 dev_err(&ua->dev->dev, "interface %u not found\n",
1249 intf_numbers[is_ua1000][i]);
1256 err = -ENXIO; 1250 err = -ENXIO;
1257 goto probe_error; 1251 goto probe_error;
1258 } 1252 }
@@ -1264,39 +1258,19 @@ static int ua101_probe(struct usb_interface *interface,
1264 goto probe_error; 1258 goto probe_error;
1265 } 1259 }
1266 } 1260 }
1267#ifdef UA1A_HACK
1268 }
1269#endif
1270 1261
1271 snd_card_set_dev(card, &interface->dev); 1262 snd_card_set_dev(card, &interface->dev);
1272 1263
1273#ifdef UA1A_HACK
1274 if (ua->dev->descriptor.idProduct == cpu_to_le16(0x0018)) {
1275 ua->format_bit = SNDRV_PCM_FMTBIT_S16_LE;
1276 ua->rate = 44100;
1277 ua->packets_per_second = 1000;
1278 ua->capture.channels = 2;
1279 ua->playback.channels = 2;
1280 ua->capture.frame_bytes = 4;
1281 ua->playback.frame_bytes = 4;
1282 ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, 2);
1283 ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, 1);
1284 ua->capture.max_packet_bytes = 192;
1285 ua->playback.max_packet_bytes = 192;
1286 } else {
1287#endif
1288 err = detect_usb_format(ua); 1264 err = detect_usb_format(ua);
1289 if (err < 0) 1265 if (err < 0)
1290 goto probe_error; 1266 goto probe_error;
1291#ifdef UA1A_HACK
1292 }
1293#endif
1294 1267
1268 name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
1295 strcpy(card->driver, "UA-101"); 1269 strcpy(card->driver, "UA-101");
1296 strcpy(card->shortname, "UA-101"); 1270 strcpy(card->shortname, name);
1297 usb_make_path(ua->dev, usb_path, sizeof(usb_path)); 1271 usb_make_path(ua->dev, usb_path, sizeof(usb_path));
1298 snprintf(ua->card->longname, sizeof(ua->card->longname), 1272 snprintf(ua->card->longname, sizeof(ua->card->longname),
1299 "EDIROL UA-101 (serial %s), %u Hz at %s, %s speed", 1273 "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
1300 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path, 1274 ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
1301 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full"); 1275 ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
1302 1276
@@ -1314,24 +1288,18 @@ static int ua101_probe(struct usb_interface *interface,
1314 if (err < 0) 1288 if (err < 0)
1315 goto probe_error; 1289 goto probe_error;
1316 1290
1317 err = snd_pcm_new(card, "UA-101", 0, 1, 1, &ua->pcm); 1291 err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
1318 if (err < 0) 1292 if (err < 0)
1319 goto probe_error; 1293 goto probe_error;
1320 ua->pcm->private_data = ua; 1294 ua->pcm->private_data = ua;
1321 strcpy(ua->pcm->name, "UA-101"); 1295 strcpy(ua->pcm->name, name);
1322 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops); 1296 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
1323 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops); 1297 snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
1324 1298
1325#ifdef UA1A_HACK
1326 if (ua->dev->descriptor.idProduct != cpu_to_le16(0x0018)) {
1327#endif
1328 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI], 1299 err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
1329 &ua->midi_list, &midi_quirk); 1300 &ua->midi_list, &midi_quirk);
1330 if (err < 0) 1301 if (err < 0)
1331 goto probe_error; 1302 goto probe_error;
1332#ifdef UA1A_HACK
1333 }
1334#endif
1335 1303
1336 err = snd_card_register(card); 1304 err = snd_card_register(card);
1337 if (err < 0) 1305 if (err < 0)
@@ -1386,11 +1354,9 @@ static void ua101_disconnect(struct usb_interface *interface)
1386} 1354}
1387 1355
1388static struct usb_device_id ua101_ids[] = { 1356static struct usb_device_id ua101_ids[] = {
1389#ifdef UA1A_HACK 1357 { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
1390 { USB_DEVICE(0x0582, 0x0018) }, 1358 { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
1391#endif 1359 { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
1392 { USB_DEVICE(0x0582, 0x007d) },
1393 { USB_DEVICE(0x0582, 0x008d) },
1394 { } 1360 { }
1395}; 1361};
1396MODULE_DEVICE_TABLE(usb, ua101_ids); 1362MODULE_DEVICE_TABLE(usb, ua101_ids);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index c539f7fe292f..11b0826b8fe6 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2483,7 +2483,6 @@ static int parse_audio_format_i_type(struct snd_usb_audio *chip,
2483 sample_width, sample_bytes); 2483 sample_width, sample_bytes);
2484 } 2484 }
2485 /* check the format byte size */ 2485 /* check the format byte size */
2486 printk(" XXXXX SAMPLE BYTES %d\n", sample_bytes);
2487 switch (sample_bytes) { 2486 switch (sample_bytes) {
2488 case 1: 2487 case 1:
2489 pcm_format = SNDRV_PCM_FORMAT_S8; 2488 pcm_format = SNDRV_PCM_FORMAT_S8;
@@ -2581,6 +2580,9 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
2581 chip->usb_id == USB_ID(0x0d8c, 0x0102)) && 2580 chip->usb_id == USB_ID(0x0d8c, 0x0102)) &&
2582 fp->altsetting == 5 && fp->maxpacksize == 392) 2581 fp->altsetting == 5 && fp->maxpacksize == 392)
2583 rate = 96000; 2582 rate = 96000;
2583 /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
2584 if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
2585 rate = 8000;
2584 fp->rate_table[fp->nr_rates] = rate; 2586 fp->rate_table[fp->nr_rates] = rate;
2585 if (!fp->rate_min || rate < fp->rate_min) 2587 if (!fp->rate_min || rate < fp->rate_min)
2586 fp->rate_min = rate; 2588 fp->rate_min = rate;
@@ -3386,58 +3388,6 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3386 return 0; 3388 return 0;
3387} 3389}
3388 3390
3389/*
3390 * Create a stream for an Edirol UA-1000 interface.
3391 */
3392static int create_ua1000_quirk(struct snd_usb_audio *chip,
3393 struct usb_interface *iface,
3394 const struct snd_usb_audio_quirk *quirk)
3395{
3396 static const struct audioformat ua1000_format = {
3397 .format = SNDRV_PCM_FORMAT_S32_LE,
3398 .fmt_type = UAC_FORMAT_TYPE_I,
3399 .altsetting = 1,
3400 .altset_idx = 1,
3401 .attributes = 0,
3402 .rates = SNDRV_PCM_RATE_CONTINUOUS,
3403 };
3404 struct usb_host_interface *alts;
3405 struct usb_interface_descriptor *altsd;
3406 struct audioformat *fp;
3407 int stream, err;
3408
3409 if (iface->num_altsetting != 2)
3410 return -ENXIO;
3411 alts = &iface->altsetting[1];
3412 altsd = get_iface_desc(alts);
3413 if (alts->extralen != 11 || alts->extra[1] != USB_DT_CS_INTERFACE ||
3414 altsd->bNumEndpoints != 1)
3415 return -ENXIO;
3416
3417 fp = kmemdup(&ua1000_format, sizeof(*fp), GFP_KERNEL);
3418 if (!fp)
3419 return -ENOMEM;
3420
3421 fp->channels = alts->extra[4];
3422 fp->iface = altsd->bInterfaceNumber;
3423 fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
3424 fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
3425 fp->datainterval = parse_datainterval(chip, alts);
3426 fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
3427 fp->rate_max = fp->rate_min = combine_triple(&alts->extra[8]);
3428
3429 stream = (fp->endpoint & USB_DIR_IN)
3430 ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
3431 err = add_audio_endpoint(chip, stream, fp);
3432 if (err < 0) {
3433 kfree(fp);
3434 return err;
3435 }
3436 /* FIXME: playback must be synchronized to capture */
3437 usb_set_interface(chip->dev, fp->iface, 0);
3438 return 0;
3439}
3440
3441static int snd_usb_create_quirk(struct snd_usb_audio *chip, 3391static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3442 struct usb_interface *iface, 3392 struct usb_interface *iface,
3443 const struct snd_usb_audio_quirk *quirk); 3393 const struct snd_usb_audio_quirk *quirk);
@@ -3686,7 +3636,6 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3686 [QUIRK_MIDI_CME] = create_any_midi_quirk, 3636 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3687 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3637 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3688 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3638 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3689 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
3690 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, 3639 [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
3691 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk 3640 [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk
3692 }; 3641 };
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6b016d4aac6b..42c299cbf63a 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -75,7 +75,6 @@ enum quirk_type {
75 QUIRK_MIDI_US122L, 75 QUIRK_MIDI_US122L,
76 QUIRK_AUDIO_STANDARD_INTERFACE, 76 QUIRK_AUDIO_STANDARD_INTERFACE,
77 QUIRK_AUDIO_FIXED_ENDPOINT, 77 QUIRK_AUDIO_FIXED_ENDPOINT,
78 QUIRK_AUDIO_EDIROL_UA1000,
79 QUIRK_AUDIO_EDIROL_UAXX, 78 QUIRK_AUDIO_EDIROL_UAXX,
80 QUIRK_AUDIO_ALIGN_TRANSFER, 79 QUIRK_AUDIO_ALIGN_TRANSFER,
81 80
@@ -112,7 +111,7 @@ struct snd_usb_midi_endpoint_info {
112 111
113/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */ 112/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
114 113
115/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */ 114/* for QUIRK_AUDIO_EDIROL_UAXX, data is NULL */
116 115
117/* for QUIRK_IGNORE_INTERFACE, data is NULL */ 116/* for QUIRK_IGNORE_INTERFACE, data is NULL */
118 117
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f06faf7917b9..2b426c1fd0e8 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1016,36 +1016,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1016 } 1016 }
1017}, 1017},
1018{ 1018{
1019 USB_DEVICE(0x0582, 0x0044),
1020 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1021 .vendor_name = "Roland",
1022 .product_name = "UA-1000",
1023 .ifnum = QUIRK_ANY_INTERFACE,
1024 .type = QUIRK_COMPOSITE,
1025 .data = (const struct snd_usb_audio_quirk[]) {
1026 {
1027 .ifnum = 1,
1028 .type = QUIRK_AUDIO_EDIROL_UA1000
1029 },
1030 {
1031 .ifnum = 2,
1032 .type = QUIRK_AUDIO_EDIROL_UA1000
1033 },
1034 {
1035 .ifnum = 3,
1036 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1037 .data = & (const struct snd_usb_midi_endpoint_info) {
1038 .out_cables = 0x0003,
1039 .in_cables = 0x0003
1040 }
1041 },
1042 {
1043 .ifnum = -1
1044 }
1045 }
1046 }
1047},
1048{
1049 /* has ID 0x0049 when not in "Advanced Driver" mode */ 1019 /* has ID 0x0049 when not in "Advanced Driver" mode */
1050 USB_DEVICE(0x0582, 0x0047), 1020 USB_DEVICE(0x0582, 0x0047),
1051 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1021 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {