From 467a44b0372d8268ce5bd90e58bde7db51c1d476 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 0001/1034] iio: adc: at91_adc: Repair broken platform_data support Trying to use the at91_adc driver while not using device tree is ending up in a kernel crash: Unable to handle kernel NULL pointer dereference at virtual address 00000004 [...] [] (at91_adc_probe) from [] (platform_drv_probe+0x18/0x48) [] (platform_drv_probe) from [] (driver_probe_device+0x100/0x218) [] (driver_probe_device) from [] (__driver_attach+0x8c/0x90) [] (__driver_attach) from [] (bus_for_each_dev+0x58/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xd4/0x1d4) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (do_one_initcall+0xe8/0x14c) [] (do_one_initcall) from [] (kernel_init_freeable+0xec/0x1b4) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xe4) [] (kernel_init) from [] (ret_from_fork+0x14/0x24) This is because the at91_adc_caps structure is mandatory but is not filled when using platform_data. Correct that by using an id_table. It ensues that the driver will not match "at91_adc" anymore but it was crashing anyway. Fixes: c46016665fff (iio: at91: ADC start-up time calculation changed since at91sam9x5) Cc: stable@vger.kernel.org # v3.13+ Signed-off-by: Alexandre Belloni Tested-by: Josh Wu Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 5b1aa027c034..bbba014c9939 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -765,14 +765,17 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, if (!pdata) return -EINVAL; + st->caps = (struct at91_adc_caps *) + platform_get_device_id(pdev)->driver_data; + st->use_external = pdata->use_external_triggers; st->vref_mv = pdata->vref; st->channels_mask = pdata->channels_used; - st->num_channels = pdata->num_channels; + st->num_channels = st->caps->num_channels; st->startup_time = pdata->startup_time; st->trigger_number = pdata->trigger_number; st->trigger_list = pdata->trigger_list; - st->registers = pdata->registers; + st->registers = &st->caps->registers; return 0; } @@ -1101,7 +1104,6 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static struct at91_adc_caps at91sam9260_caps = { .calc_startup_ticks = calc_startup_ticks_9260, .num_channels = 4, @@ -1154,11 +1156,27 @@ static const struct of_device_id at91_adc_dt_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); -#endif + +static const struct platform_device_id at91_adc_ids[] = { + { + .name = "at91sam9260-adc", + .driver_data = (unsigned long)&at91sam9260_caps, + }, { + .name = "at91sam9g45-adc", + .driver_data = (unsigned long)&at91sam9g45_caps, + }, { + .name = "at91sam9x5-adc", + .driver_data = (unsigned long)&at91sam9x5_caps, + }, { + /* terminator */ + } +}; +MODULE_DEVICE_TABLE(platform, at91_adc_ids); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, .remove = at91_adc_remove, + .id_table = at91_adc_ids, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(at91_adc_dt_ids), From 41c897f8789d0d1039ed873ddcd0caabd5756e0f Mon Sep 17 00:00:00 2001 From: Beomho Seo Date: Wed, 3 Dec 2014 00:57:00 +0000 Subject: [PATCH 0002/1034] iio: cm32181: Fix read integration time function In read integration time function, assign 0 to val. Because, prevent return inaccurate value when call read integration time. Cc: Stable@vger.kernel.org Cc: Kevin Tsai Signed-off-by: Beomho Seo Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm32181.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 47a6dbac2d0c..d976e6ce60db 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -221,6 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, *val = cm32181->calibscale; return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: + *val = 0; ret = cm32181_read_als_it(cm32181, val2); return ret; } From 142df13b7598d88de5b163464e74d2101912f479 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 0003/1034] ARM: at91: at91sam9g45: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index cb36fa872d30..88554024eb2d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1203,7 +1203,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9g45-adc", .id = -1, .dev = { .platform_data = &adc_data, From 301841a634976c1cef4490cae577ffd0f26d0149 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 0004/1034] ARM: at91: at91sam9260: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index eda8d1679d40..0a0315920963 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -1292,7 +1292,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9260-adc", .id = -1, .dev = { .platform_data = &adc_data, From 8f32b6ba56ef8c8434635b9f08ff6a23510960a5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 3 Mar 2014 18:07:00 +0000 Subject: [PATCH 0005/1034] iio: adc: at91_adc: correct default shtim value When sample_hold_time is zero (this is the case when DT is not used or if atmel,adc-sample-hold-time is omitted), then the calculated shtim is large. Make that 0, which is the default for that register and the ADC will then use a sane value of 2/ADCCLK or 1/ADCCLK depending on the version. Signed-off-by: Alexandre Belloni Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index bbba014c9939..89777ed9abd8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1007,8 +1007,11 @@ static int at91_adc_probe(struct platform_device *pdev) * the best converted final value between two channels selection * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock */ - shtim = round_up((st->sample_hold_time * adc_clk_khz / - 1000) - 1, 1); + if (st->sample_hold_time > 0) + shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000) + - 1, 1); + else + shtim = 0; reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; From 6b9da2e77249bd62bb0902319cfa22398f32c538 Mon Sep 17 00:00:00 2001 From: Jimmy Li Date: Sat, 22 Mar 2014 05:58:00 +0000 Subject: [PATCH 0006/1034] staging:iio:ad2s1200 fix a missing break Signed-off-by: Jimmy Li Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 36eedd8a0ea9..e2b482045158 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -70,6 +70,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); vel = (vel << 4) >> 4; *val = vel; + break; default: mutex_unlock(&st->lock); return -EINVAL; From 2076a20fc1a06f7b0333c62a2bb4eeeac7ed1bcb Mon Sep 17 00:00:00 2001 From: Alec Berg Date: Wed, 19 Mar 2014 18:50:00 +0000 Subject: [PATCH 0007/1034] iio: querying buffer scan_mask should return 0/1 Ensure that querying the IIO buffer scan_mask returns a value of 0 or 1. Currently querying the scan mask has the value returned by test_bit(), which returns either true or false. For some architectures test_bit() may return -1 for true, which will appear to return an error when returning from iio_scan_mask_query(). Additionally, it's important for the sysfs interface to consistently return the same thing when querying the scan_mask. Signed-off-by: Alec Berg Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c67d83bdc8f0..fe25042f056a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -165,7 +165,8 @@ static ssize_t iio_scan_el_show(struct device *dev, int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); - ret = test_bit(to_iio_dev_attr(attr)->address, + /* Ensure ret is 0 or 1. */ + ret = !!test_bit(to_iio_dev_attr(attr)->address, indio_dev->buffer->scan_mask); return sprintf(buf, "%d\n", ret); @@ -866,7 +867,8 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, if (!buffer->scan_mask) return 0; - return test_bit(bit, buffer->scan_mask); + /* Ensure return value is 0 or 1. */ + return !!test_bit(bit, buffer->scan_mask); }; EXPORT_SYMBOL_GPL(iio_scan_mask_query); From d0a588a57c2b0748df8307a0865a1bbbf1624c53 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 18 Mar 2014 08:13:00 +0000 Subject: [PATCH 0008/1034] iio: cm36651: Fix i2c client leak and possible NULL pointer dereference During probe the driver allocates dummy I2C devices (i2c_new_dummy()) but they aren't unregistered during driver remove or probe failure. Additionally driver does not check the return value of i2c_new_dummy(). In case of error (i2c_new_device(): memory allocation failure or I2C address cannot be used) this function returns NULL which is later dereferenced by i2c_smbus_{read,write}_data() functions. Fix issues by properly checking for i2c_new_dummy() return value and unregistering I2C devices on driver remove or probe failure. Signed-off-by: Krzysztof Kozlowski Acked-by: Beomho Seo Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm36651.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index a45e07492db3..39fc67e82138 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -652,7 +652,19 @@ static int cm36651_probe(struct i2c_client *client, cm36651->client = client; cm36651->ps_client = i2c_new_dummy(client->adapter, CM36651_I2C_ADDR_PS); + if (!cm36651->ps_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_disable_reg; + } + cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA); + if (!cm36651->ara_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_i2c_unregister_ps; + } + mutex_init(&cm36651->lock); indio_dev->dev.parent = &client->dev; indio_dev->channels = cm36651_channels; @@ -664,7 +676,7 @@ static int cm36651_probe(struct i2c_client *client, ret = cm36651_setup_reg(cm36651); if (ret) { dev_err(&client->dev, "%s: register setup failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler, @@ -672,7 +684,7 @@ static int cm36651_probe(struct i2c_client *client, "cm36651", indio_dev); if (ret) { dev_err(&client->dev, "%s: request irq failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = iio_device_register(indio_dev); @@ -685,6 +697,10 @@ static int cm36651_probe(struct i2c_client *client, error_free_irq: free_irq(client->irq, indio_dev); +error_i2c_unregister_ara: + i2c_unregister_device(cm36651->ara_client); +error_i2c_unregister_ps: + i2c_unregister_device(cm36651->ps_client); error_disable_reg: regulator_disable(cm36651->vled_reg); return ret; @@ -698,6 +714,8 @@ static int cm36651_remove(struct i2c_client *client) iio_device_unregister(indio_dev); regulator_disable(cm36651->vled_reg); free_irq(client->irq, indio_dev); + i2c_unregister_device(cm36651->ps_client); + i2c_unregister_device(cm36651->ara_client); return 0; } From e036f71e8ce310dc58b1351c3eb967b892f4641c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 17 Mar 2014 16:43:00 +0000 Subject: [PATCH 0009/1034] iio: adc: mxs-lradc: fix warning when buidling on avr32 This fixes: drivers/staging/iio/adc/mxs-lradc.c: In function 'mxs_lradc_probe': drivers/staging/iio/adc/mxs-lradc.c:1558: warning: comparison of distinct pointer types lacks a cast drivers/staging/iio/adc/mxs-lradc.c:1558: warning: right shift count >= width of type drivers/staging/iio/adc/mxs-lradc.c:1558: warning: passing argument 1 of '__div64_32' from incompatible pointer type When building on avr32. Reported-by: Fengguang Wu Signed-off-by: Alexandre Belloni Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/mxs-lradc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index 514844efac75..53b3f963a7e3 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1527,7 +1527,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) struct resource *iores; int ret = 0, touch_ret; int i, s; - unsigned int scale_uv; + uint64_t scale_uv; /* Allocate the IIO device. */ iio = devm_iio_device_alloc(dev, sizeof(*lradc)); From eb8451e0aee1816395506e97965d0917754072de Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 27 Feb 2014 14:41:14 +0100 Subject: [PATCH 0010/1034] xtensa: Export __invalidate_icache_range When modular code calls flush_icache_range(): ERROR: "__invalidate_icache_range" [drivers/misc/lkdtm.ko] undefined! make[1]: *** [__modpost] Error 1 Signed-off-by: Geert Uytterhoeven Reviewed-by: Kees Cook Signed-off-by: Max Filippov --- arch/xtensa/kernel/xtensa_ksyms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 80b33ed51f31..88eab32be29e 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -105,6 +105,7 @@ EXPORT_SYMBOL(csum_partial_copy_generic); * Architecture-specific symbols */ EXPORT_SYMBOL(__xtensa_copy_user); +EXPORT_SYMBOL(__invalidate_icache_range); /* * Kernel hacking ... From a3cfda9d2f9ca067a2757b9d85d98cfbaf1e8c63 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 21 Mar 2014 21:05:16 +0400 Subject: [PATCH 0011/1034] xtensa: export __{invalidate,flush}_dcache_range Signed-off-by: Max Filippov --- arch/xtensa/kernel/xtensa_ksyms.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 88eab32be29e..4d2872fd9bb5 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -128,3 +129,8 @@ EXPORT_SYMBOL(common_exception_return); #ifdef CONFIG_FUNCTION_TRACER EXPORT_SYMBOL(_mcount); #endif + +EXPORT_SYMBOL(__invalidate_dcache_range); +#if XCHAL_DCACHE_IS_WRITEBACK +EXPORT_SYMBOL(__flush_dcache_range); +#endif From 25df8198f4b257cf6db4d4f000c53accfa9c28f8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 18 Feb 2014 15:29:11 +0400 Subject: [PATCH 0012/1034] xtensa: enable sorting extable at build time Signed-off-by: Max Filippov Acked-by: David Daney --- arch/xtensa/Kconfig | 1 + scripts/sortextable.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index c87ae7c6e5f9..df6f86ca6c1a 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -14,6 +14,7 @@ config XTENSA select GENERIC_PCI_IOMAP select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_OPTIONAL_GPIOLIB + select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS select IRQ_DOMAIN select HAVE_OPROFILE diff --git a/scripts/sortextable.c b/scripts/sortextable.c index cc49062acdee..1052d4834a44 100644 --- a/scripts/sortextable.c +++ b/scripts/sortextable.c @@ -35,6 +35,10 @@ #define EM_ARCOMPACT 93 #endif +#ifndef EM_XTENSA +#define EM_XTENSA 94 +#endif + #ifndef EM_AARCH64 #define EM_AARCH64 183 #endif @@ -281,6 +285,7 @@ do_file(char const *const fname) case EM_AARCH64: case EM_MICROBLAZE: case EM_MIPS: + case EM_XTENSA: break; } /* end switch */ From 9ba067f93f1eec0d241f002812806b873dd4f802 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 23 Mar 2014 03:17:43 +0400 Subject: [PATCH 0013/1034] xtensa: split bootparam and kernel meminfo Bootparam meminfo is a bootloader ABI, kernel meminfo is for the kernel bookkeeping, keep them separate. Kernel doesn't care of memory region types, so drop the type field and don't pass it to add_sysmem_bank. Move kernel sysmem structures and prototypes to asm/sysmem.h and sysmem variable and add_sysmem_bank to mm/init.c Signed-off-by: Max Filippov --- arch/xtensa/include/asm/bootparam.h | 13 ++------- arch/xtensa/include/asm/sysmem.h | 33 ++++++++++++++++++++++ arch/xtensa/kernel/setup.c | 43 ++++++----------------------- arch/xtensa/mm/init.c | 17 ++++++++++++ 4 files changed, 61 insertions(+), 45 deletions(-) create mode 100644 arch/xtensa/include/asm/sysmem.h diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 23392c5630ce..892aab399ac8 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h @@ -37,23 +37,14 @@ typedef struct bp_tag { unsigned long data[0]; /* data */ } bp_tag_t; -typedef struct meminfo { +struct bp_meminfo { unsigned long type; unsigned long start; unsigned long end; -} meminfo_t; - -#define SYSMEM_BANKS_MAX 5 +}; #define MEMORY_TYPE_CONVENTIONAL 0x1000 #define MEMORY_TYPE_NONE 0x2000 -typedef struct sysmem_info { - int nr_banks; - meminfo_t bank[SYSMEM_BANKS_MAX]; -} sysmem_info_t; - -extern sysmem_info_t sysmem; - #endif #endif diff --git a/arch/xtensa/include/asm/sysmem.h b/arch/xtensa/include/asm/sysmem.h new file mode 100644 index 000000000000..fe7ad750a158 --- /dev/null +++ b/arch/xtensa/include/asm/sysmem.h @@ -0,0 +1,33 @@ +/* + * sysmem-related prototypes. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2014 Cadence Design Systems Inc. + */ + +#ifndef _XTENSA_SYSMEM_H +#define _XTENSA_SYSMEM_H + +#define SYSMEM_BANKS_MAX 31 + +struct meminfo { + unsigned long start; + unsigned long end; +}; + +struct sysmem_info { + int nr_banks; + struct meminfo bank[SYSMEM_BANKS_MAX]; +}; + +extern struct sysmem_info sysmem; + +int add_sysmem_bank(unsigned long start, unsigned long end); +int mem_reserve(unsigned long, unsigned long, int); +void bootmem_init(void); +void zones_init(void); + +#endif /* _XTENSA_SYSMEM_H */ diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 84fe931bb60e..df2b1d6fc843 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -50,6 +50,7 @@ #include #include #include +#include #include @@ -88,12 +89,6 @@ static char __initdata command_line[COMMAND_LINE_SIZE]; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; #endif -sysmem_info_t __initdata sysmem; - -extern int mem_reserve(unsigned long, unsigned long, int); -extern void bootmem_init(void); -extern void zones_init(void); - /* * Boot parameter parsing. * @@ -113,31 +108,14 @@ typedef struct tagtable { /* parse current tag */ -static int __init add_sysmem_bank(unsigned long type, unsigned long start, - unsigned long end) -{ - if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { - printk(KERN_WARNING - "Ignoring memory bank 0x%08lx size %ldKB\n", - start, end - start); - return -EINVAL; - } - sysmem.bank[sysmem.nr_banks].type = type; - sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); - sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; - sysmem.nr_banks++; - - return 0; -} - static int __init parse_tag_mem(const bp_tag_t *tag) { - meminfo_t *mi = (meminfo_t *)(tag->data); + struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); if (mi->type != MEMORY_TYPE_CONVENTIONAL) return -1; - return add_sysmem_bank(mi->type, mi->start, mi->end); + return add_sysmem_bank(mi->start, mi->end); } __tagtable(BP_TAG_MEMORY, parse_tag_mem); @@ -146,8 +124,8 @@ __tagtable(BP_TAG_MEMORY, parse_tag_mem); static int __init parse_tag_initrd(const bp_tag_t* tag) { - meminfo_t* mi; - mi = (meminfo_t*)(tag->data); + struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); + initrd_start = (unsigned long)__va(mi->start); initrd_end = (unsigned long)__va(mi->end); @@ -255,7 +233,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) return; size &= PAGE_MASK; - add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); + add_sysmem_bank(base, base + size); } void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) @@ -292,8 +270,6 @@ device_initcall(xtensa_device_probe); void __init init_arch(bp_tag_t *bp_start) { - sysmem.nr_banks = 0; - /* Parse boot parameters */ if (bp_start) @@ -304,10 +280,9 @@ void __init init_arch(bp_tag_t *bp_start) #endif if (sysmem.nr_banks == 0) { - sysmem.nr_banks = 1; - sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; - sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START - + PLATFORM_DEFAULT_MEM_SIZE; + add_sysmem_bank(PLATFORM_DEFAULT_MEM_START, + PLATFORM_DEFAULT_MEM_START + + PLATFORM_DEFAULT_MEM_SIZE); } #ifdef CONFIG_CMDLINE_BOOL diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index aff108df92d3..4f78264e8bd8 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -27,6 +27,23 @@ #include #include #include +#include + +struct sysmem_info sysmem __initdata; + +int __init add_sysmem_bank(unsigned long start, unsigned long end) +{ + if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { + pr_warn("Ignoring memory bank 0x%08lx size %ldKB\n", + start, end - start); + return -EINVAL; + } + sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); + sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; + sysmem.nr_banks++; + + return 0; +} /* * mem_reserve(start, end, must_exist) From 9d4b52df4b1242e6ba9a00db5f8d62083a56709f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 23 Mar 2014 03:34:44 +0400 Subject: [PATCH 0014/1034] xtensa: keep sysmem banks ordered in add_sysmem_bank Rewrite add_sysmem_bank so that it keeps bank order and merges adjacent/overlapping banks. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/sysmem.h | 5 ++ arch/xtensa/mm/init.c | 103 +++++++++++++++++++++++++++++-- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/include/asm/sysmem.h b/arch/xtensa/include/asm/sysmem.h index fe7ad750a158..c015c5c8e3f7 100644 --- a/arch/xtensa/include/asm/sysmem.h +++ b/arch/xtensa/include/asm/sysmem.h @@ -18,6 +18,11 @@ struct meminfo { unsigned long end; }; +/* + * Bank array is sorted by .start. + * Banks don't overlap and there's at least one page gap + * between adjacent bank entries. + */ struct sysmem_info { int nr_banks; struct meminfo bank[SYSMEM_BANKS_MAX]; diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 4f78264e8bd8..79c0c3d52ae3 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -8,6 +8,7 @@ * for more details. * * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2014 Cadence Design Systems Inc. * * Chris Zankel * Joe Taylor @@ -31,17 +32,109 @@ struct sysmem_info sysmem __initdata; +/* + * Find bank with maximal .start such that bank.start <= start + */ +static inline struct meminfo * __init find_bank(unsigned long start) +{ + unsigned i; + struct meminfo *it = NULL; + + for (i = 0; i < sysmem.nr_banks; ++i) + if (sysmem.bank[i].start <= start) + it = sysmem.bank + i; + else + break; + return it; +} + +/* + * Move all memory banks starting at 'from' to a new place at 'to', + * adjust nr_banks accordingly. + * Both 'from' and 'to' must be inside the sysmem.bank. + * + * Returns: 0 (success), -ENOMEM (not enough space in the sysmem.bank). + */ +static int __init move_banks(struct meminfo *to, struct meminfo *from) +{ + unsigned n = sysmem.nr_banks - (from - sysmem.bank); + + if (to > from && to - from + sysmem.nr_banks > SYSMEM_BANKS_MAX) + return -ENOMEM; + if (to != from) + memmove(to, from, n * sizeof(struct meminfo)); + sysmem.nr_banks += to - from; + return 0; +} + +/* + * Add new bank to sysmem. Resulting sysmem is the union of bytes of the + * original sysmem and the new bank. + * + * Returns: 0 (success), < 0 (error) + */ int __init add_sysmem_bank(unsigned long start, unsigned long end) { - if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { - pr_warn("Ignoring memory bank 0x%08lx size %ldKB\n", + unsigned i; + struct meminfo *it = NULL; + unsigned long sz; + unsigned long bank_sz = 0; + + if (start == end || + (start < end) != (PAGE_ALIGN(start) < (end & PAGE_MASK))) { + pr_warn("Ignoring small memory bank 0x%08lx size: %ld bytes\n", start, end - start); return -EINVAL; } - sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); - sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; - sysmem.nr_banks++; + start = PAGE_ALIGN(start); + end &= PAGE_MASK; + sz = end - start; + + it = find_bank(start); + + if (it) + bank_sz = it->end - it->start; + + if (it && bank_sz >= start - it->start) { + if (end - it->start > bank_sz) + it->end = end; + else + return 0; + } else { + if (!it) + it = sysmem.bank; + else + ++it; + + if (it - sysmem.bank < sysmem.nr_banks && + it->start - start <= sz) { + it->start = start; + if (it->end - it->start < sz) + it->end = end; + else + return 0; + } else { + if (move_banks(it + 1, it) < 0) { + pr_warn("Ignoring memory bank 0x%08lx size %ld bytes\n", + start, end - start); + return -EINVAL; + } + it->start = start; + it->end = end; + return 0; + } + } + sz = it->end - it->start; + for (i = it + 1 - sysmem.bank; i < sysmem.nr_banks; ++i) + if (sysmem.bank[i].start - it->start <= sz) { + if (sz < sysmem.bank[i].end - it->start) + it->end = sysmem.bank[i].end; + } else { + break; + } + + move_banks(it + 1, sysmem.bank + i); return 0; } From 6232791833785ae591b211609f6f7c4faa7c6e55 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 23 Mar 2014 03:24:45 +0400 Subject: [PATCH 0015/1034] xtensa: keep sysmem banks ordered in mem_reserve Rewrite mem_reserve so that it keeps bank order. Also make its return code more traditional. Signed-off-by: Max Filippov --- arch/xtensa/kernel/setup.c | 2 +- arch/xtensa/mm/init.c | 86 +++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 35 deletions(-) diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index df2b1d6fc843..017c06aba9b2 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -462,7 +462,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start < initrd_end) { initrd_is_mapped = mem_reserve(__pa(initrd_start), - __pa(initrd_end), 0); + __pa(initrd_end), 0) == 0; initrd_below_start_ok = 1; } else { initrd_start = 0; diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 79c0c3d52ae3..5d23697957bf 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -142,6 +142,8 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end) * mem_reserve(start, end, must_exist) * * Reserve some memory from the memory pool. + * If must_exist is set and a part of the region being reserved does not exist + * memory map is not altered. * * Parameters: * start Start of region, @@ -149,53 +151,69 @@ int __init add_sysmem_bank(unsigned long start, unsigned long end) * must_exist Must exist in memory pool. * * Returns: - * 0 (memory area couldn't be mapped) - * -1 (success) + * 0 (success) + * < 0 (error) */ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) { - int i; - - if (start == end) - return 0; + struct meminfo *it; + struct meminfo *rm = NULL; + unsigned long sz; + unsigned long bank_sz = 0; start = start & PAGE_MASK; end = PAGE_ALIGN(end); + sz = end - start; + if (!sz) + return -EINVAL; - for (i = 0; i < sysmem.nr_banks; i++) - if (start < sysmem.bank[i].end - && end >= sysmem.bank[i].start) - break; + it = find_bank(start); - if (i == sysmem.nr_banks) { - if (must_exist) - printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) " - "not in any region!\n", start, end); - return 0; + if (it) + bank_sz = it->end - it->start; + + if ((!it || end - it->start > bank_sz) && must_exist) { + pr_warn("mem_reserve: [0x%0lx, 0x%0lx) not in any region!\n", + start, end); + return -EINVAL; } - if (start > sysmem.bank[i].start) { - if (end < sysmem.bank[i].end) { - /* split entry */ - if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) - panic("meminfo overflow\n"); - sysmem.bank[sysmem.nr_banks].start = end; - sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end; - sysmem.nr_banks++; + if (it && start - it->start < bank_sz) { + if (start == it->start) { + if (end - it->start < bank_sz) { + it->start = end; + return 0; + } else { + rm = it; + } + } else { + it->end = start; + if (end - it->start < bank_sz) + return add_sysmem_bank(end, + it->start + bank_sz); + ++it; } - sysmem.bank[i].end = start; - - } else if (end < sysmem.bank[i].end) { - sysmem.bank[i].start = end; - - } else { - /* remove entry */ - sysmem.nr_banks--; - sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; - sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; } - return -1; + + if (!it) + it = sysmem.bank; + + for (; it < sysmem.bank + sysmem.nr_banks; ++it) { + if (it->end - start <= sz) { + if (!rm) + rm = it; + } else { + if (it->start - start < sz) + it->start = end; + break; + } + } + + if (rm) + move_banks(rm, it); + + return 0; } From 06bd2824f7dcbfb8dcd13519239a53d13298d238 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 21 Mar 2014 21:04:40 +0400 Subject: [PATCH 0016/1034] xtensa: handle memmap kernel option This option is useful for reserving memory regions for secondary cores in AMP configurations. Implement the following memmap variants: - memmap=nn[KMG]@ss[KMG]: force usage of a specific region of memory; - memmap=nn[KMG]$ss[KMG]: mark specified memory as reserved; - memmap=nn[KMG]: set end of memory. Signed-off-by: Max Filippov --- arch/xtensa/kernel/setup.c | 1 + arch/xtensa/mm/init.c | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 017c06aba9b2..9757bb74e532 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -507,6 +507,7 @@ void __init setup_arch(char **cmdline_p) __pa(&_Level6InterruptVector_text_end), 0); #endif + parse_early_param(); bootmem_init(); unflatten_and_copy_device_tree(); diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 5d23697957bf..d70ba9333f44 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -332,3 +332,53 @@ void free_initmem(void) { free_initmem_default(-1); } + +static void __init parse_memmap_one(char *p) +{ + char *oldp; + unsigned long start_at, mem_size; + + if (!p) + return; + + oldp = p; + mem_size = memparse(p, &p); + if (p == oldp) + return; + + switch (*p) { + case '@': + start_at = memparse(p + 1, &p); + add_sysmem_bank(start_at, start_at + mem_size); + break; + + case '$': + start_at = memparse(p + 1, &p); + mem_reserve(start_at, start_at + mem_size, 0); + break; + + case 0: + mem_reserve(mem_size, 0, 0); + break; + + default: + pr_warn("Unrecognized memmap syntax: %s\n", p); + break; + } +} + +static int __init parse_memmap_opt(char *str) +{ + while (str) { + char *k = strchr(str, ','); + + if (k) + *k++ = 0; + + parse_memmap_one(str); + str = k; + } + + return 0; +} +early_param("memmap", parse_memmap_opt); From 8585b316bbed9339412d267c1fd8839dd059d69f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 23 Mar 2014 03:26:46 +0400 Subject: [PATCH 0017/1034] xtensa: dump sysmem from the bootmem_init Debug dump of physical memory configuration. Useful for inspection of resulting memory map, esp. in the presence of memmap= kernel option. Signed-off-by: Max Filippov --- arch/xtensa/mm/init.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index d70ba9333f44..03bd025307e3 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -32,6 +32,17 @@ struct sysmem_info sysmem __initdata; +static void __init sysmem_dump(void) +{ + unsigned i; + + pr_debug("Sysmem:\n"); + for (i = 0; i < sysmem.nr_banks; ++i) + pr_debug(" 0x%08lx - 0x%08lx (%ldK)\n", + sysmem.bank[i].start, sysmem.bank[i].end, + (sysmem.bank[i].end - sysmem.bank[i].start) >> 10); +} + /* * Find bank with maximal .start such that bank.start <= start */ @@ -227,6 +238,7 @@ void __init bootmem_init(void) unsigned long bootmap_start, bootmap_size; int i; + sysmem_dump(); max_low_pfn = max_pfn = 0; min_low_pfn = ~0; From 74c03eb63061c834893e7ebf8d298573bdccfd08 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Apr 2014 12:41:59 -0400 Subject: [PATCH 0018/1034] libata: make AHCI_XGENE depend on PHY_XGENE AHCI_XGENE is only applicable on ARM64 but it can also be enabled for compile testing; however, AHCI_XGENE selects PHY_XGENE which has other arch specific dependencies. This leads to the following warning when enabling it on other archs for compile testing. warning: (AHCI_XGENE) selects PHY_XGENE which has unmet direct dependencies (HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)) Selecting a config option which itself has dependencies can easily lead to broken configurations. For now, let's just make AHCI_XGENE depend on PHY_XGENE which has all the necessary dependencies already. Signed-off-by: Tejun Heo Reported-by: Linus Torvalds Cc: Loc Ho Cc: Bartlomiej Zolnierkiewicz Cc: Kishon Vijay Abraham I --- drivers/ata/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 20e03a7eb8b4..2e4da3bc47fc 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -134,8 +134,7 @@ config AHCI_SUNXI config AHCI_XGENE tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" - depends on ARM64 || COMPILE_TEST - select PHY_XGENE + depends on PHY_XGENE help This option enables support for APM X-Gene SoC SATA host controller. From d121f7d0cbb875abce249dbf7eb191f9bafe80b7 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 1 Apr 2014 20:42:37 -0400 Subject: [PATCH 0019/1034] libata: Update queued trim blacklist for M5x0 drives Crucial/Micron M500 drives properly support queued DSM TRIM starting with firmware MU05. Update the blacklist so we only disable queued trim for older firmware releases. Early M550 series drives suffer from the same issue as M500. A bugfix firmware is in the pipeline but not ready yet. Until then, blacklist queued trim for M550. Signed-off-by: Martin K. Petersen Cc: Chris Samuel Cc: Marc MERLIN Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- drivers/ata/libata-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 34406f7fdd7a..f2a6020366e1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* devices that don't properly handle queued TRIM commands */ - { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, /* * Some WD SATA-I drives spin up and down erratically when the link From 27aa64b9d1bd0d23fd692c91763a48309b694311 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 31 Mar 2014 19:51:14 +0200 Subject: [PATCH 0020/1034] pata_at91: fix ata_host_activate() failure handling Add missing clk_put() call to ata_host_activate() failure path. Sergei says, "Hm, I have once fixed that (see that *if* (!ret)) but looks like a later commit 477c87e90853d136b188c50c0e4a93d01cad872e (ARM: at91/pata: use gpio_is_valid to check the gpio) broke it again. :-( Would be good if the changelog did mention that..." Cc: Andrew Victor Cc: Nicolas Ferre Cc: Jean-Christophe Plagniol-Villard Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- drivers/ata/pata_at91.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index e9c87274a781..8a66f23af4c4 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -407,12 +407,13 @@ static int pata_at91_probe(struct platform_device *pdev) host->private_data = info; - return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, - gpio_is_valid(irq) ? ata_sff_interrupt : NULL, - irq_flags, &pata_at91_sht); + ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, + gpio_is_valid(irq) ? ata_sff_interrupt : NULL, + irq_flags, &pata_at91_sht); + if (ret) + goto err_put; - if (!ret) - return 0; + return 0; err_put: clk_put(info->mck); From 378ed3ccd2a0404d031e771b65aa3af221ea8aea Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 3 Apr 2014 10:53:43 -0700 Subject: [PATCH 0021/1034] x86, vdso: Make the vdso linker script compatible with Gold Gold can't parse the script due to: https://sourceware.org/bugzilla/show_bug.cgi?id=16804 With a workaround in place for that issue, Gold 2.23 crashes due to: https://sourceware.org/bugzilla/show_bug.cgi?id=15355 This works around the former bug and avoids the second by removing the unnecessary vvar and hpet sections and segments. The vdso and hpet symbols are still there, and nothing needed the sections or segments. Reported-by: Markus Trippelsdorf Signed-off-by: Andy Lutomirski Link: http://lkml.kernel.org/r/243fa205098d112ec759c9b1b26785c09f399833.1396547532.git.luto@amacapital.net Signed-off-by: H. Peter Anvin --- arch/x86/vdso/vdso-layout.lds.S | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S index 2e263f367b13..9df017ab2285 100644 --- a/arch/x86/vdso/vdso-layout.lds.S +++ b/arch/x86/vdso/vdso-layout.lds.S @@ -9,12 +9,9 @@ SECTIONS #ifdef BUILD_VDSO32 #include - .hpet_sect : { - hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); - } :text :hpet_sect + hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); - .vvar_sect : { - vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); + vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); /* Place all vvars at the offsets in asm/vvar.h. */ #define EMIT_VVAR(name, offset) vvar_ ## name = vvar + offset; @@ -22,7 +19,6 @@ SECTIONS #include #undef __VVAR_KERNEL_LDS #undef EMIT_VVAR - } :text :vvar_sect #endif . = SIZEOF_HEADERS; @@ -61,7 +57,12 @@ SECTIONS */ . = ALIGN(0x100); - .text : { *(.text*) } :text =0x90909090 + .text : { *(.text*) } :text =0x90909090, + + /* + * The comma above works around a bug in gold: + * https://sourceware.org/bugzilla/show_bug.cgi?id=16804 + */ /DISCARD/ : { *(.discard) @@ -84,8 +85,4 @@ PHDRS dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ note PT_NOTE FLAGS(4); /* PF_R */ eh_frame_hdr PT_GNU_EH_FRAME; -#ifdef BUILD_VDSO32 - vvar_sect PT_NULL FLAGS(4); /* PF_R */ - hpet_sect PT_NULL FLAGS(4); /* PF_R */ -#endif } From 04c6b3e2b5e5c1dbd99ad7620033eafd05ff4c26 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 14 Feb 2014 14:08:48 +0400 Subject: [PATCH 0022/1034] xtensa: optimize local_flush_tlb_kernel_range Don't flush whole TLB if only a small kernel range is requested. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/tlbflush.h | 11 ++++------- arch/xtensa/kernel/smp.c | 15 +++++++++++++++ arch/xtensa/mm/tlb.c | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/arch/xtensa/include/asm/tlbflush.h b/arch/xtensa/include/asm/tlbflush.h index fc34274ce41b..06875feb27c2 100644 --- a/arch/xtensa/include/asm/tlbflush.h +++ b/arch/xtensa/include/asm/tlbflush.h @@ -36,6 +36,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifdef CONFIG_SMP @@ -44,12 +45,7 @@ void flush_tlb_mm(struct mm_struct *); void flush_tlb_page(struct vm_area_struct *, unsigned long); void flush_tlb_range(struct vm_area_struct *, unsigned long, unsigned long); - -static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ - flush_tlb_all(); -} +void flush_tlb_kernel_range(unsigned long start, unsigned long end); #else /* !CONFIG_SMP */ @@ -58,7 +54,8 @@ static inline void flush_tlb_kernel_range(unsigned long start, #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \ end) -#define flush_tlb_kernel_range(start, end) local_flush_tlb_all() +#define flush_tlb_kernel_range(start, end) local_flush_tlb_kernel_range(start, \ + end) #endif /* CONFIG_SMP */ diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index aa8bd8717927..40b5a3771fb0 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -496,6 +496,21 @@ void flush_tlb_range(struct vm_area_struct *vma, on_each_cpu(ipi_flush_tlb_range, &fd, 1); } +static void ipi_flush_tlb_kernel_range(void *arg) +{ + struct flush_data *fd = arg; + local_flush_tlb_kernel_range(fd->addr1, fd->addr2); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct flush_data fd = { + .addr1 = start, + .addr2 = end, + }; + on_each_cpu(ipi_flush_tlb_kernel_range, &fd, 1); +} + /* Cache flush functions */ static void ipi_flush_cache_all(void *arg) diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index ade623826788..5ece856c5725 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c @@ -149,6 +149,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) local_irq_restore(flags); } +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + if (end > start && start >= TASK_SIZE && end <= PAGE_OFFSET && + end - start < _TLB_ENTRIES << PAGE_SHIFT) { + start &= PAGE_MASK; + while (start < end) { + invalidate_itlb_mapping(start); + invalidate_dtlb_mapping(start); + start += PAGE_SIZE; + } + } else { + local_flush_tlb_all(); + } +} + #ifdef CONFIG_DEBUG_TLB_SANITY static unsigned get_pte_for_vaddr(unsigned vaddr) From 65559100655c6ed6ce2e17ffc8d4f3852bc2858a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 4 Feb 2014 02:17:09 +0400 Subject: [PATCH 0023/1034] xtensa: add HIGHMEM support Introduce fixmap area just below the vmalloc region. Use it for atomic mapping of high memory pages. High memory on cores with cache aliasing is not supported and is still to be implemented. Fail build for such configurations for now. Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 18 ++++++++ arch/xtensa/include/asm/fixmap.h | 58 +++++++++++++++++++++++++ arch/xtensa/include/asm/highmem.h | 45 ++++++++++++++++++- arch/xtensa/include/asm/pgtable.h | 4 ++ arch/xtensa/mm/Makefile | 1 + arch/xtensa/mm/cache.c | 7 ++- arch/xtensa/mm/highmem.c | 72 +++++++++++++++++++++++++++++++ arch/xtensa/mm/init.c | 45 +++++++++++++------ arch/xtensa/mm/mmu.c | 36 ++++++++++++++++ 9 files changed, 270 insertions(+), 16 deletions(-) create mode 100644 arch/xtensa/include/asm/fixmap.h create mode 100644 arch/xtensa/mm/highmem.c diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index df6f86ca6c1a..17b31982c566 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -190,6 +190,24 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX If in doubt, say Y. +config HIGHMEM + bool "High Memory Support" + help + Linux can use the full amount of RAM in the system by + default. However, the default MMUv2 setup only maps the + lowermost 128 MB of memory linearly to the areas starting + at 0xd0000000 (cached) and 0xd8000000 (uncached). + When there are more than 128 MB memory in the system not + all of it can be "permanently mapped" by the kernel. + The physical memory that's not permanently mapped is called + "high memory". + + If you are compiling a kernel which will never run on a + machine with more than 128 MB total physical RAM, answer + N here. + + If unsure, say Y. + endmenu config XTENSA_CALIBRATE_CCOUNT diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h new file mode 100644 index 000000000000..9f6c33d0428a --- /dev/null +++ b/arch/xtensa/include/asm/fixmap.h @@ -0,0 +1,58 @@ +/* + * fixmap.h: compile-time virtual memory allocation + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1998 Ingo Molnar + * + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + */ + +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +#include +#ifdef CONFIG_HIGHMEM +#include +#include +#endif + +/* + * Here we define all the compile-time 'special' virtual + * addresses. The point is to have a constant address at + * compile time, but to set the physical address only + * in the boot process. We allocate these special addresses + * from the end of the consistent memory region backwards. + * Also this lets us do fail-safe vmalloc(), we + * can guarantee that these special addresses and + * vmalloc()-ed addresses never overlap. + * + * these 'compile-time allocated' memory buffers are + * fixed-size 4k pages. (or larger if used with an increment + * higher than 1) use fixmap_set(idx,phys) to associate + * physical memory with fixmap indices. + */ +enum fixed_addresses { +#ifdef CONFIG_HIGHMEM + /* reserved pte's for temporary kernel mappings */ + FIX_KMAP_BEGIN, + FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, +#endif + __end_of_fixed_addresses +}; + +#define FIXADDR_TOP (VMALLOC_START - PAGE_SIZE) +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) + +#include + +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel( \ + pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \ + (vaddr) \ + ) + +#endif diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 80be15124697..2653ef5d55f1 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h @@ -6,11 +6,54 @@ * this archive for more details. * * Copyright (C) 2003 - 2005 Tensilica Inc. + * Copyright (C) 2014 Cadence Design Systems Inc. */ #ifndef _XTENSA_HIGHMEM_H #define _XTENSA_HIGHMEM_H -extern void flush_cache_kmaps(void); +#include +#include +#include +#include + +#define PKMAP_BASE (FIXADDR_START - PMD_SIZE) +#define LAST_PKMAP PTRS_PER_PTE +#define LAST_PKMAP_MASK (LAST_PKMAP - 1) +#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +#define kmap_prot PAGE_KERNEL + +extern pte_t *pkmap_page_table; + +void *kmap_high(struct page *page); +void kunmap_high(struct page *page); + +static inline void *kmap(struct page *page) +{ + BUG_ON(in_interrupt()); + if (!PageHighMem(page)) + return page_address(page); + return kmap_high(page); +} + +static inline void kunmap(struct page *page) +{ + BUG_ON(in_interrupt()); + if (!PageHighMem(page)) + return; + kunmap_high(page); +} + +static inline void flush_cache_kmaps(void) +{ + flush_cache_all(); +} + +void *kmap_atomic(struct page *page); +void __kunmap_atomic(void *kvaddr); + +void kmap_init(void); #endif diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 216446295ada..4b0ca35a93b1 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h @@ -310,6 +310,10 @@ set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) update_pte(ptep, pteval); } +static inline void set_pte(pte_t *ptep, pte_t pteval) +{ + update_pte(ptep, pteval); +} static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval) diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index f0b646d2f843..f54f78e24d7b 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile @@ -4,3 +4,4 @@ obj-y := init.o cache.o misc.o obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o +obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index ba4c47f291b1..63cbb867dadd 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -59,6 +59,10 @@ * */ +#if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) +#error "HIGHMEM is not supported on cores with aliasing cache." +#endif + #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK /* @@ -179,10 +183,11 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) #else if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) && (vma->vm_flags & VM_EXEC) != 0) { - unsigned long paddr = (unsigned long) page_address(page); + unsigned long paddr = (unsigned long)kmap_atomic(page); __flush_dcache_page(paddr); __invalidate_icache_page(paddr); set_bit(PG_arch_1, &page->flags); + kunmap_atomic((void *)paddr); } #endif } diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c new file mode 100644 index 000000000000..17a8c0d6fd17 --- /dev/null +++ b/arch/xtensa/mm/highmem.c @@ -0,0 +1,72 @@ +/* + * High memory support for Xtensa architecture + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file "COPYING" in the main directory of + * this archive for more details. + * + * Copyright (C) 2014 Cadence Design Systems Inc. + */ + +#include +#include +#include + +static pte_t *kmap_pte; + +void *kmap_atomic(struct page *page) +{ + enum fixed_addresses idx; + unsigned long vaddr; + int type; + + pagefault_disable(); + if (!PageHighMem(page)) + return page_address(page); + + type = kmap_atomic_idx_push(); + idx = type + KM_TYPE_NR * smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(!pte_none(*(kmap_pte - idx))); +#endif + set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); + + return (void *)vaddr; +} +EXPORT_SYMBOL(kmap_atomic); + +void __kunmap_atomic(void *kvaddr) +{ + int idx, type; + + if (kvaddr >= (void *)FIXADDR_START && + kvaddr < (void *)FIXADDR_TOP) { + type = kmap_atomic_idx(); + idx = type + KM_TYPE_NR * smp_processor_id(); + + /* + * Force other mappings to Oops if they'll try to access this + * pte without first remap it. Keeping stale mappings around + * is a bad idea also, in case the page changes cacheability + * attributes or becomes a protected page in a hypervisor. + */ + pte_clear(&init_mm, kvaddr, kmap_pte - idx); + local_flush_tlb_kernel_range((unsigned long)kvaddr, + (unsigned long)kvaddr + PAGE_SIZE); + + kmap_atomic_idx_pop(); + } + + pagefault_enable(); +} +EXPORT_SYMBOL(__kunmap_atomic); + +void __init kmap_init(void) +{ + unsigned long kmap_vstart; + + /* cache the first kmap pte */ + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); + kmap_pte = kmap_get_fixmap_pte(kmap_vstart); +} diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 03bd025307e3..4224256bb215 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -296,19 +297,13 @@ void __init bootmem_init(void) void __init zones_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; - int i; - /* All pages are DMA-able, so we put them all in the DMA zone. */ - - zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET; - for (i = 1; i < MAX_NR_ZONES; i++) - zones_size[i] = 0; - + unsigned long zones_size[MAX_NR_ZONES] = { + [ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET, #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; + [ZONE_HIGHMEM] = max_pfn - max_low_pfn, #endif - + }; free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); } @@ -318,16 +313,38 @@ void __init zones_init(void) void __init mem_init(void) { - max_mapnr = max_low_pfn - ARCH_PFN_OFFSET; - high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); - #ifdef CONFIG_HIGHMEM -#error HIGHGMEM not implemented in init.c + unsigned long tmp; + + reset_all_zones_managed_pages(); + for (tmp = max_low_pfn; tmp < max_pfn; tmp++) + free_highmem_page(pfn_to_page(tmp)); #endif + max_mapnr = max_pfn - ARCH_PFN_OFFSET; + high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT); + free_all_bootmem(); mem_init_print_info(NULL); + pr_info("virtual kernel memory layout:\n" +#ifdef CONFIG_HIGHMEM + " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n" + " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" +#endif + " vmalloc : 0x%08x - 0x%08x (%5u MB)\n" + " lowmem : 0x%08x - 0x%08lx (%5lu MB)\n", +#ifdef CONFIG_HIGHMEM + PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, + (LAST_PKMAP*PAGE_SIZE) >> 10, + FIXADDR_START, FIXADDR_TOP, + (FIXADDR_TOP - FIXADDR_START) >> 10, +#endif + VMALLOC_START, VMALLOC_END, + (VMALLOC_END - VMALLOC_START) >> 20, + PAGE_OFFSET, PAGE_OFFSET + + (max_low_pfn - min_low_pfn) * PAGE_SIZE, + ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20); } #ifdef CONFIG_BLK_DEV_INITRD diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 861203e958da..3429b483d9f8 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -3,6 +3,7 @@ * * Extracted from init.c */ +#include #include #include #include @@ -16,9 +17,44 @@ #include #include +#if defined(CONFIG_HIGHMEM) +static void * __init init_pmd(unsigned long vaddr) +{ + pgd_t *pgd = pgd_offset_k(vaddr); + pmd_t *pmd = pmd_offset(pgd, vaddr); + + if (pmd_none(*pmd)) { + unsigned i; + pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); + + for (i = 0; i < 1024; i++) + pte_clear(NULL, 0, pte + i); + + set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); + BUG_ON(pte != pte_offset_kernel(pmd, 0)); + pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", + __func__, vaddr, pmd, pte); + return pte; + } else { + return pte_offset_kernel(pmd, 0); + } +} + +static void __init fixedrange_init(void) +{ + BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); + init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); +} +#endif + void __init paging_init(void) { memset(swapper_pg_dir, 0, PAGE_SIZE); +#ifdef CONFIG_HIGHMEM + fixedrange_init(); + pkmap_page_table = init_pmd(PKMAP_BASE); + kmap_init(); +#endif } /* From 08a7bbf624072bed1cb35e5b4db7d538580f731c Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 23 Feb 2014 03:48:32 +0400 Subject: [PATCH 0024/1034] xtensa: xtfpga: introduce SoC I/O bus Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | 48 +++++++++++----------- arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | 32 ++++++++------- arch/xtensa/boot/dts/xtfpga.dtsi | 37 ++++++++++------- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi index e5703c7beeb6..1d97203c18e7 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi @@ -1,26 +1,28 @@ / { - flash: flash@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0xf8000000 0x01000000>; - bank-width = <2>; - device-width = <2>; - partition@0x0 { - label = "boot loader area"; - reg = <0x00000000 0x00400000>; + soc { + flash: flash@08000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x08000000 0x01000000>; + bank-width = <2>; + device-width = <2>; + partition@0x0 { + label = "boot loader area"; + reg = <0x00000000 0x00400000>; + }; + partition@0x400000 { + label = "kernel image"; + reg = <0x00400000 0x00600000>; + }; + partition@0xa00000 { + label = "data"; + reg = <0x00a00000 0x005e0000>; + }; + partition@0xfe0000 { + label = "boot environment"; + reg = <0x00fe0000 0x00020000>; + }; }; - partition@0x400000 { - label = "kernel image"; - reg = <0x00400000 0x00600000>; - }; - partition@0xa00000 { - label = "data"; - reg = <0x00a00000 0x005e0000>; - }; - partition@0xfe0000 { - label = "boot environment"; - reg = <0x00fe0000 0x00020000>; - }; - }; + }; }; diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi index 6f9c10d6b689..d1c621ca8be1 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi @@ -1,18 +1,20 @@ / { - flash: flash@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0xf8000000 0x00400000>; - bank-width = <2>; - device-width = <2>; - partition@0x0 { - label = "boot loader area"; - reg = <0x00000000 0x003f0000>; + soc { + flash: flash@08000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x08000000 0x00400000>; + bank-width = <2>; + device-width = <2>; + partition@0x0 { + label = "boot loader area"; + reg = <0x00000000 0x003f0000>; + }; + partition@0x3f0000 { + label = "boot environment"; + reg = <0x003f0000 0x00010000>; + }; }; - partition@0x3f0000 { - label = "boot environment"; - reg = <0x003f0000 0x00010000>; - }; - }; + }; }; diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index e7370b11348e..dec9178840f6 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -42,21 +42,28 @@ }; }; - serial0: serial@fd050020 { - device_type = "serial"; - compatible = "ns16550a"; - no-loopback-test; - reg = <0xfd050020 0x20>; - reg-shift = <2>; - interrupts = <0 1>; /* external irq 0 */ - clocks = <&osc>; - }; + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x00000000 0xf0000000 0x10000000>; - enet0: ethoc@fd030000 { - compatible = "opencores,ethoc"; - reg = <0xfd030000 0x4000 0xfd800000 0x4000>; - interrupts = <1 1>; /* external irq 1 */ - local-mac-address = [00 50 c2 13 6f 00]; - clocks = <&osc>; + serial0: serial@0d050020 { + device_type = "serial"; + compatible = "ns16550a"; + no-loopback-test; + reg = <0x0d050020 0x20>; + reg-shift = <2>; + interrupts = <0 1>; /* external irq 0 */ + clocks = <&osc>; + }; + + enet0: ethoc@0d030000 { + compatible = "opencores,ethoc"; + reg = <0x0d030000 0x4000 0x0d800000 0x4000>; + interrupts = <1 1>; /* external irq 1 */ + local-mac-address = [00 50 c2 13 6f 00]; + clocks = <&osc>; + }; }; }; From 9c602629e34bad88a464e08de08118e80beee0d8 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 28 Apr 2013 19:15:56 +0400 Subject: [PATCH 0025/1034] xtensa: add support for KC705 Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/kc705.dts | 11 ++++++++ arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi | 28 +++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 arch/xtensa/boot/dts/kc705.dts create mode 100644 arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts new file mode 100644 index 000000000000..742a347be67a --- /dev/null +++ b/arch/xtensa/boot/dts/kc705.dts @@ -0,0 +1,11 @@ +/dts-v1/; +/include/ "xtfpga.dtsi" +/include/ "xtfpga-flash-128m.dtsi" + +/ { + compatible = "cdns,xtensa-kc705"; + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x08000000>; + }; +}; diff --git a/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi new file mode 100644 index 000000000000..d3a88e029873 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi @@ -0,0 +1,28 @@ +/ { + soc { + flash: flash@00000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0x00000000 0x08000000>; + bank-width = <2>; + device-width = <2>; + partition@0x0 { + label = "data"; + reg = <0x00000000 0x06000000>; + }; + partition@0x6000000 { + label = "boot loader area"; + reg = <0x06000000 0x00800000>; + }; + partition@0x6800000 { + label = "kernel image"; + reg = <0x06800000 0x017e0000>; + }; + partition@0x7fe0000 { + label = "boot environment"; + reg = <0x07fe0000 0x00020000>; + }; + }; + }; +}; From 666525dfbdca09bbd4848ac711e4a4dbd6921325 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Mon, 7 Apr 2014 10:18:56 -0400 Subject: [PATCH 0026/1034] ext4: fix 64-bit number truncation warning '0x7FDEADBEEF' will be truncated to 32-bit number under unicore32. Need append 'ULL' for it. The related warning (with allmodconfig under unicore32): CC [M] fs/ext4/extents_status.o fs/ext4/extents_status.c: In function "__es_remove_extent": fs/ext4/extents_status.c:813: warning: integer constant is too large for "long" type Signed-off-by: Chen Gang Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents_status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 0a014a7194b2..0ebc21204b51 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -810,7 +810,7 @@ retry: newes.es_lblk = end + 1; newes.es_len = len2; - block = 0x7FDEADBEEF; + block = 0x7FDEADBEEFULL; if (ext4_es_is_written(&orig_es) || ext4_es_is_unwritten(&orig_es)) block = ext4_es_pblock(&orig_es) + From 4adb6ab3e0fa71363a5ef229544b2d17de6600d7 Mon Sep 17 00:00:00 2001 From: Kazuya Mio Date: Mon, 7 Apr 2014 10:53:28 -0400 Subject: [PATCH 0027/1034] ext4: FIBMAP ioctl causes BUG_ON due to handle EXT_MAX_BLOCKS When we try to get 2^32-1 block of the file which has the extent (ee_block=2^32-2, ee_len=1) with FIBMAP ioctl, it causes BUG_ON in ext4_ext_put_gap_in_cache(). To avoid the problem, ext4_map_blocks() needs to check the file logical block number. ext4_ext_put_gap_in_cache() called via ext4_map_blocks() cannot handle 2^32-1 because the maximum file logical block number is 2^32-2. Note that ext4_ind_map_blocks() returns -EIO when the block number is invalid. So ext4_map_blocks() should also return the same errno. Signed-off-by: Kazuya Mio Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5b0d2c7d5408..93f16c5e8a8e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -522,6 +522,10 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, if (unlikely(map->m_len > INT_MAX)) map->m_len = INT_MAX; + /* We can handle the block number less than EXT_MAX_BLOCKS */ + if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS)) + return -EIO; + /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { ext4_es_lru_add(inode); From 007649375f6af242d5b1df2c15996949714303ba Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 7 Apr 2014 10:54:20 -0400 Subject: [PATCH 0028/1034] ext4: initialize multi-block allocator before checking block descriptors With EXT4FS_DEBUG ext4_count_free_clusters() will call ext4_read_block_bitmap() without s_group_info initialized, so we need to initialize multi-block allocator before. And dependencies that must be solved, to allow this: - multi-block allocator needs in group descriptors - need to install s_op before initializing multi-block allocator, because in ext4_mb_init_backend() new inode is created. - initialize number of group desc blocks (s_gdb_count) otherwise number of clusters returned by ext4_free_clusters_after_init() is not correct. (see ext4_bg_num_gdb_nometa()) Here is the stack backtrace: (gdb) bt #0 ext4_get_group_info (group=0, sb=0xffff880079a10000) at ext4.h:2430 #1 ext4_validate_block_bitmap (sb=sb@entry=0xffff880079a10000, desc=desc@entry=0xffff880056510000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:358 #2 0xffffffff81232202 in ext4_wait_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:476 #3 0xffffffff81232eaf in ext4_read_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0) at balloc.c:489 #4 0xffffffff81232fc0 in ext4_count_free_clusters (sb=sb@entry=0xffff880079a10000) at balloc.c:665 #5 0xffffffff81259ffa in ext4_check_descriptors (first_not_zeroed=, sb=0xffff880079a10000) at super.c:2143 #6 ext4_fill_super (sb=sb@entry=0xffff880079a10000, data=, data@entry=0x0 , silent=silent@entry=0) at super.c:3851 ... Signed-off-by: Azat Khuzhin Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f3c667091618..6f9e6fadac04 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3869,19 +3869,38 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount2; } } + + /* + * set up enough so that it can read an inode, + * and create new inode for buddy allocator + */ + sbi->s_gdb_count = db_count; + if (!test_opt(sb, NOLOAD) && + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) + sb->s_op = &ext4_sops; + else + sb->s_op = &ext4_nojournal_sops; + + ext4_ext_init(sb); + err = ext4_mb_init(sb); + if (err) { + ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", + err); + goto failed_mount2; + } + if (!ext4_check_descriptors(sb, &first_not_zeroed)) { ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); - goto failed_mount2; + goto failed_mount2a; } if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) if (!ext4_fill_flex_info(sb)) { ext4_msg(sb, KERN_ERR, "unable to initialize " "flex_bg meta info!"); - goto failed_mount2; + goto failed_mount2a; } - sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); @@ -3916,14 +3935,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_stripe = ext4_get_stripe_size(sbi); sbi->s_extent_max_zeroout_kb = 32; - /* - * set up enough so that it can read an inode - */ - if (!test_opt(sb, NOLOAD) && - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) - sb->s_op = &ext4_sops; - else - sb->s_op = &ext4_nojournal_sops; sb->s_export_op = &ext4_export_ops; sb->s_xattr = ext4_xattr_handlers; #ifdef CONFIG_QUOTA @@ -4113,21 +4124,13 @@ no_journal: if (err) { ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for " "reserved pool", ext4_calculate_resv_clusters(sb)); - goto failed_mount4a; + goto failed_mount5; } err = ext4_setup_system_zone(sb); if (err) { ext4_msg(sb, KERN_ERR, "failed to initialize system " "zone (%d)", err); - goto failed_mount4a; - } - - ext4_ext_init(sb); - err = ext4_mb_init(sb); - if (err) { - ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", - err); goto failed_mount5; } @@ -4204,11 +4207,8 @@ failed_mount8: failed_mount7: ext4_unregister_li_request(sb); failed_mount6: - ext4_mb_release(sb); -failed_mount5: - ext4_ext_release(sb); ext4_release_system_zone(sb); -failed_mount4a: +failed_mount5: dput(sb->s_root); sb->s_root = NULL; failed_mount4: @@ -4232,11 +4232,14 @@ failed_mount3: percpu_counter_destroy(&sbi->s_extent_cache_cnt); if (sbi->s_mmp_tsk) kthread_stop(sbi->s_mmp_tsk); +failed_mount2a: + ext4_mb_release(sb); failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); ext4_kvfree(sbi->s_group_desc); failed_mount: + ext4_ext_release(sb); if (sbi->s_chksum_driver) crypto_free_shash(sbi->s_chksum_driver); if (sbi->s_proc) { From 9503c67c93ed0b95ba62d12d1fd09da6245dbdd6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 7 Apr 2014 10:54:20 -0400 Subject: [PATCH 0029/1034] ext4: note the error in ext4_end_bio() ext4_end_bio() currently throws away the error that it receives. Chances are this is part of a spate of errors, one of which will end up getting the error returned to userspace somehow, but we shouldn't take that risk. Also print out the errno to aid in debug. Signed-off-by: Matthew Wilcox Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: stable@vger.kernel.org --- fs/ext4/page-io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index ab95508e3d40..c18d95b50540 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -308,13 +308,14 @@ static void ext4_end_bio(struct bio *bio, int error) if (error) { struct inode *inode = io_end->inode; - ext4_warning(inode->i_sb, "I/O error writing to inode %lu " + ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu " "(offset %llu size %ld starting block %llu)", - inode->i_ino, + error, inode->i_ino, (unsigned long long) io_end->offset, (long) io_end->size, (unsigned long long) bi_sector >> (inode->i_blkbits - 9)); + mapping_set_error(inode->i_mapping, error); } if (io_end->flag & EXT4_IO_END_UNWRITTEN) { From ec4cb1aa2b7bae18dd8164f2e9c7c51abcf61280 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 7 Apr 2014 10:54:21 -0400 Subject: [PATCH 0030/1034] ext4: fix jbd2 warning under heavy xattr load When heavily exercising xattr code the assertion that jbd2_journal_dirty_metadata() shouldn't return error was triggered: WARNING: at /srv/autobuild-ceph/gitbuilder.git/build/fs/jbd2/transaction.c:1237 jbd2_journal_dirty_metadata+0x1ba/0x260() CPU: 0 PID: 8877 Comm: ceph-osd Tainted: G W 3.10.0-ceph-00049-g68d04c9 #1 Hardware name: Dell Inc. PowerEdge R410/01V648, BIOS 1.6.3 02/07/2011 ffffffff81a1d3c8 ffff880214469928 ffffffff816311b0 ffff880214469968 ffffffff8103fae0 ffff880214469958 ffff880170a9dc30 ffff8802240fbe80 0000000000000000 ffff88020b366000 ffff8802256e7510 ffff880214469978 Call Trace: [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x70/0xa0 [] warn_slowpath_null+0x1a/0x20 [] jbd2_journal_dirty_metadata+0x1ba/0x260 [] __ext4_handle_dirty_metadata+0xa3/0x140 [] ext4_xattr_release_block+0x103/0x1f0 [] ext4_xattr_block_set+0x1e0/0x910 [] ext4_xattr_set_handle+0x38b/0x4a0 [] ? trace_hardirqs_on+0xd/0x10 [] ext4_xattr_set+0xc2/0x140 [] ext4_xattr_user_set+0x47/0x50 [] generic_setxattr+0x6e/0x90 [] __vfs_setxattr_noperm+0x7b/0x1c0 [] vfs_setxattr+0xc4/0xd0 [] setxattr+0x13e/0x1e0 [] ? __sb_start_write+0xe7/0x1b0 [] ? mnt_want_write_file+0x28/0x60 [] ? fget_light+0x3c/0x130 [] ? mnt_want_write_file+0x28/0x60 [] ? __mnt_want_write+0x58/0x70 [] SyS_fsetxattr+0xbe/0x100 [] system_call_fastpath+0x16/0x1b The reason for the warning is that buffer_head passed into jbd2_journal_dirty_metadata() didn't have journal_head attached. This is caused by the following race of two ext4_xattr_release_block() calls: CPU1 CPU2 ext4_xattr_release_block() ext4_xattr_release_block() lock_buffer(bh); /* False */ if (BHDR(bh)->h_refcount == cpu_to_le32(1)) } else { le32_add_cpu(&BHDR(bh)->h_refcount, -1); unlock_buffer(bh); lock_buffer(bh); /* True */ if (BHDR(bh)->h_refcount == cpu_to_le32(1)) get_bh(bh); ext4_free_blocks() ... jbd2_journal_forget() jbd2_journal_unfile_buffer() -> JH is gone error = ext4_handle_dirty_xattr_block(handle, inode, bh); -> triggers the warning We fix the problem by moving ext4_handle_dirty_xattr_block() under the buffer lock. Sadly this cannot be done in nojournal mode as that function can call sync_dirty_buffer() which would deadlock. Luckily in nojournal mode the race is harmless (we only dirty already freed buffer) and thus for nojournal mode we leave the dirtying outside of the buffer lock. Reported-by: Sage Weil Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/xattr.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 1f5cf5880718..4eec399ec807 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -520,8 +520,8 @@ static void ext4_xattr_update_super_block(handle_t *handle, } /* - * Release the xattr block BH: If the reference count is > 1, decrement - * it; otherwise free the block. + * Release the xattr block BH: If the reference count is > 1, decrement it; + * otherwise free the block. */ static void ext4_xattr_release_block(handle_t *handle, struct inode *inode, @@ -542,16 +542,31 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, if (ce) mb_cache_entry_free(ce); get_bh(bh); + unlock_buffer(bh); ext4_free_blocks(handle, inode, bh, 0, 1, EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); - unlock_buffer(bh); } else { le32_add_cpu(&BHDR(bh)->h_refcount, -1); if (ce) mb_cache_entry_release(ce); + /* + * Beware of this ugliness: Releasing of xattr block references + * from different inodes can race and so we have to protect + * from a race where someone else frees the block (and releases + * its journal_head) before we are done dirtying the buffer. In + * nojournal mode this race is harmless and we actually cannot + * call ext4_handle_dirty_xattr_block() with locked buffer as + * that function can call sync_dirty_buffer() so for that case + * we handle the dirtying after unlocking the buffer. + */ + if (ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); unlock_buffer(bh); - error = ext4_handle_dirty_xattr_block(handle, inode, bh); + if (!ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); if (IS_SYNC(inode)) ext4_handle_sync(handle); dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1)); From 0d606c08f44a09e3ca86d4af1a40aec61a6e9dde Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:45:58 +0100 Subject: [PATCH 0031/1034] ARM: Kirkwood: Fix Atmel vendor prefix The documented vendor prefix for Atmel is 'atmel' not 'at' as used in these .dts[i] files. The i2c framework actually ignores the prefix, so making this change does not cause compatibility issues. Signed-off-by: Andrew Lunn Link: https://lkml.kernel.org/r/1395492360-1865-4-git-send-email-andrew@lunn.ch Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood-laplug.dts | 2 +- arch/arm/boot/dts/kirkwood-ns2-common.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-laplug.dts b/arch/arm/boot/dts/kirkwood-laplug.dts index c9e82eff9bf2..6761ffa2c4ab 100644 --- a/arch/arm/boot/dts/kirkwood-laplug.dts +++ b/arch/arm/boot/dts/kirkwood-laplug.dts @@ -48,7 +48,7 @@ status = "okay"; eeprom@50 { - compatible = "at,24c04"; + compatible = "atmel,24c04"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 743152f31a81..843eb478b3e4 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -50,7 +50,7 @@ status = "okay"; eeprom@50 { - compatible = "at,24c04"; + compatible = "atmel,24c04"; pagesize = <16>; reg = <0x50>; }; From dcdf9cfc4868878957d5c372f82b233143ec4320 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:46:00 +0100 Subject: [PATCH 0032/1034] ARM: Kirkwood: DT: Add missing vendor prefix Add vendor prefixes to compatible strings where they are missing. Both the I2C and MTD framework ignore the prefix, so adding them has no effect on backwards compatibility. Signed-off-by: Andrew Lunn Link: https://lkml.kernel.org/r/1395492360-1865-6-git-send-email-andrew@lunn.ch Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood-b3.dts | 2 +- arch/arm/boot/dts/kirkwood-cloudbox.dts | 2 +- arch/arm/boot/dts/kirkwood-dreamplug.dts | 2 +- arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 2 +- arch/arm/boot/dts/kirkwood-ns2-common.dtsi | 2 +- arch/arm/boot/dts/kirkwood-nsa310.dts | 2 +- arch/arm/boot/dts/kirkwood-nsa310a.dts | 2 +- arch/arm/boot/dts/kirkwood-openblocks_a6.dts | 2 +- arch/arm/boot/dts/kirkwood-openblocks_a7.dts | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-b3.dts b/arch/arm/boot/dts/kirkwood-b3.dts index 40791053106b..6becedebaa4e 100644 --- a/arch/arm/boot/dts/kirkwood-b3.dts +++ b/arch/arm/boot/dts/kirkwood-b3.dts @@ -75,7 +75,7 @@ m25p16@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "m25p16"; + compatible = "st,m25p16"; reg = <0>; spi-max-frequency = <40000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-cloudbox.dts b/arch/arm/boot/dts/kirkwood-cloudbox.dts index 0e06fd3cee4d..3b62aeeaa3a2 100644 --- a/arch/arm/boot/dts/kirkwood-cloudbox.dts +++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts @@ -46,7 +46,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l4005a"; + compatible = "mxicy,mx25l4005a"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index ef3463e0ae19..28b3ee369778 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -43,7 +43,7 @@ m25p40@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l1606e"; + compatible = "mxicy,mx25l1606e"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts index dc86429756d7..25cbaaae142e 100644 --- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts +++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts @@ -56,7 +56,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l12805d"; + compatible = "mxicy,mx25l12805d"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 843eb478b3e4..e6e5ec4fe6b9 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -32,7 +32,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l4005a"; + compatible = "mxicy,mx25l4005a"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index 03fa24cf3344..0a07af9d8e58 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -104,7 +104,7 @@ status = "okay"; adt7476: adt7476a@2e { - compatible = "adt7476"; + compatible = "adi,adt7476"; reg = <0x2e>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-nsa310a.dts b/arch/arm/boot/dts/kirkwood-nsa310a.dts index a5e779452867..27ca6a79c48a 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310a.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310a.dts @@ -94,7 +94,7 @@ status = "okay"; lm85: lm85@2e { - compatible = "lm85"; + compatible = "national,lm85"; reg = <0x2e>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index b88da9392c32..0650beafc1de 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -40,7 +40,7 @@ pinctrl-names = "default"; s35390a: s35390a@30 { - compatible = "s35390a"; + compatible = "sii,s35390a"; reg = <0x30>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts index b2f7cae06839..38520a287514 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts @@ -52,7 +52,7 @@ pinctrl-names = "default"; s24c02: s24c02@50 { - compatible = "24c02"; + compatible = "atmel,24c02"; reg = <0x50>; }; }; From a6e03dd451c724f785277d8ecca5d1a0b886d892 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 26 Mar 2014 00:33:58 +0100 Subject: [PATCH 0033/1034] ARM: mvebu: ensure the mdio node has a clock reference on Armada 370/XP The mvmdio driver accesses some register of the Ethernet unit. It therefore takes a reference and enables a clock. However, on Armada 370/XP, no clock specification was given in the Device Tree, which leads the mvmdio driver to fail when being used as a module and loaded before the mvneta driver: it tries to access a register from a hardware unit that isn't clocked. Cc: stable@vger.kernel.org Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1395790439-21332-2-git-send-email-thomas.petazzoni@free-electrons.com Acked-by: Andrew Lunn Acked-by: Gregory CLEMENT Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-xp.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index bbb40f62037d..bb77970c0b12 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -230,6 +230,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x72004 0x4>; + clocks = <&gateclk 4>; }; eth1: ethernet@74000 { From 33faf20b8ebe2770f2d7b52796f5f35eeb87ab6f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 26 Mar 2014 00:33:59 +0100 Subject: [PATCH 0034/1034] ARM: mvebu: ensure the mdio node has a clock reference on Armada 38x The mvmdio driver accesses some register of the Ethernet unit. It therefore takes a reference and enables a clock. However, on Armada 38x, no clock specification was given in the Device Tree, which leads the mvmdio driver to fail when being used as a module and loaded before the mvneta driver: it tries to access a register from a hardware unit that isn't clocked. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1395790439-21332-3-git-send-email-thomas.petazzoni@free-electrons.com Acked-by: Andrew Lunn Acked-by: Gregory CLEMENT Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-38x.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index a064f59da02d..ca8813bb99ba 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -336,6 +336,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x72004 0x4>; + clocks = <&gateclk 4>; }; coredivclk: clock@e4250 { From b08eed0c4d7d70eae2f4f1ff518cc33643722a07 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Mon, 7 Apr 2014 20:16:52 +0100 Subject: [PATCH 0035/1034] ARM: shmobile: lager: correct renesas,gpios to renesas,groups in sd[02] pfc Fix probable typo of renesas,groups in the lager dt. The kernel has no renesas,gpios but this should match renesas,groups. Signed-off-by: Rob Taylor [ben.dooks@codethink.co.uk: fixup description] Signed-off-by: Ben Dooks Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 6e99eb2df076..d01048ab3e77 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -141,12 +141,12 @@ }; sdhi0_pins: sd0 { - renesas,gpios = "sdhi0_data4", "sdhi0_ctrl"; + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; renesas,function = "sdhi0"; }; sdhi2_pins: sd2 { - renesas,gpios = "sdhi2_data4", "sdhi2_ctrl"; + renesas,groups = "sdhi2_data4", "sdhi2_ctrl"; renesas,function = "sdhi2"; }; From f5f85ee065f2e243f4165d7dd7d1a4a95daa1801 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 8 Apr 2014 11:06:26 +0200 Subject: [PATCH 0036/1034] ata: fix i.MX AHCI driver dependencies The ahci_imx driver is only needed on Freescale i.MX platforms so don't let it be built on other platforms, except for build test purpose. Signed-off-by: Jean Delvare Cc: Tejun Heo Cc: Richard Zhu Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2e4da3bc47fc..c2706047337f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -116,7 +116,7 @@ config AHCI_ST config AHCI_IMX tristate "Freescale i.MX AHCI SATA support" - depends on MFD_SYSCON + depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) help This option enables support for the Freescale i.MX SoC's onboard AHCI SATA. From 5e3283e2920a0bd8a806964d80274b8756e0dd7f Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 8 Apr 2014 11:08:41 +0100 Subject: [PATCH 0037/1034] dm thin: irqsave must always be used with the pool->lock spinlock Commit c140e1c4e23 ("dm thin: use per thin device deferred bio lists") incorrectly stopped disabling irqs when taking the pool's spinlock. Irqs must be disabled when taking the pool's spinlock otherwise a thread could spin_lock(), then get interrupted to service thin_endio() in interrupt context, which would then deadlock in spin_lock_irqsave(). Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-thin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 53728be84dee..ae5fd0b9c75c 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3101,6 +3101,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) struct thin_c *tc; struct dm_dev *pool_dev, *origin_dev; struct mapped_device *pool_md; + unsigned long flags; mutex_lock(&dm_thin_pool_table.mutex); @@ -3191,9 +3192,9 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) mutex_unlock(&dm_thin_pool_table.mutex); - spin_lock(&tc->pool->lock); + spin_lock_irqsave(&tc->pool->lock, flags); list_add_tail_rcu(&tc->list, &tc->pool->active_thins); - spin_unlock(&tc->pool->lock); + spin_unlock_irqrestore(&tc->pool->lock, flags); /* * This synchronize_rcu() call is needed here otherwise we risk a * wake_worker() call finding no bios to process (because the newly From b10ebd34cccae1b431caf1be54919aede2be7cbe Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 8 Apr 2014 11:29:01 +0100 Subject: [PATCH 0038/1034] dm thin: fix rcu_read_lock being held in code that can sleep Commit c140e1c4e23 ("dm thin: use per thin device deferred bio lists") introduced the use of an rculist for all active thin devices. The use of rcu_read_lock() in process_deferred_bios() can result in a BUG if a dm_bio_prison_cell must be allocated as a side-effect of bio_detain(): BUG: sleeping function called from invalid context at mm/mempool.c:203 in_atomic(): 1, irqs_disabled(): 0, pid: 6, name: kworker/u8:0 3 locks held by kworker/u8:0/6: #0: ("dm-" "thin"){.+.+..}, at: [] process_one_work+0x192/0x550 #1: ((&pool->worker)){+.+...}, at: [] process_one_work+0x192/0x550 #2: (rcu_read_lock){.+.+..}, at: [] do_worker+0x5/0x4d0 We can't process deferred bios with the rcu lock held, since dm_bio_prison_cell allocation may block if the bio-prison's cell mempool is exhausted. To fix: - Introduce a refcount and completion field to each thin_c - Add thin_get/put methods for adjusting the refcount. If the refcount hits zero then the completion is triggered. - Initialise refcount to 1 when creating thin_c - When iterating the active_thins list we thin_get() whilst the rcu lock is held. - After the rcu lock is dropped we process the deferred bios for that thin. - When destroying a thin_c we thin_put() and then wait for the completion -- to avoid a race between the worker thread iterating from that thin_c and destroying the thin_c. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-thin.c | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ae5fd0b9c75c..28fc282b61b2 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -232,6 +232,13 @@ struct thin_c { struct bio_list deferred_bio_list; struct bio_list retry_on_resume_list; struct rb_root sort_bio_list; /* sorted list of deferred bios */ + + /* + * Ensures the thin is not destroyed until the worker has finished + * iterating the active_thins list. + */ + atomic_t refcount; + struct completion can_destroy; }; /*----------------------------------------------------------------*/ @@ -1486,6 +1493,45 @@ static void process_thin_deferred_bios(struct thin_c *tc) blk_finish_plug(&plug); } +static void thin_get(struct thin_c *tc); +static void thin_put(struct thin_c *tc); + +/* + * We can't hold rcu_read_lock() around code that can block. So we + * find a thin with the rcu lock held; bump a refcount; then drop + * the lock. + */ +static struct thin_c *get_first_thin(struct pool *pool) +{ + struct thin_c *tc = NULL; + + rcu_read_lock(); + if (!list_empty(&pool->active_thins)) { + tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); + thin_get(tc); + } + rcu_read_unlock(); + + return tc; +} + +static struct thin_c *get_next_thin(struct pool *pool, struct thin_c *tc) +{ + struct thin_c *old_tc = tc; + + rcu_read_lock(); + list_for_each_entry_continue_rcu(tc, &pool->active_thins, list) { + thin_get(tc); + thin_put(old_tc); + rcu_read_unlock(); + return tc; + } + thin_put(old_tc); + rcu_read_unlock(); + + return NULL; +} + static void process_deferred_bios(struct pool *pool) { unsigned long flags; @@ -1493,10 +1539,11 @@ static void process_deferred_bios(struct pool *pool) struct bio_list bios; struct thin_c *tc; - rcu_read_lock(); - list_for_each_entry_rcu(tc, &pool->active_thins, list) + tc = get_first_thin(pool); + while (tc) { process_thin_deferred_bios(tc); - rcu_read_unlock(); + tc = get_next_thin(pool, tc); + } /* * If there are any deferred flush bios, we must commit @@ -3061,11 +3108,25 @@ static struct target_type pool_target = { /*---------------------------------------------------------------- * Thin target methods *--------------------------------------------------------------*/ +static void thin_get(struct thin_c *tc) +{ + atomic_inc(&tc->refcount); +} + +static void thin_put(struct thin_c *tc) +{ + if (atomic_dec_and_test(&tc->refcount)) + complete(&tc->can_destroy); +} + static void thin_dtr(struct dm_target *ti) { struct thin_c *tc = ti->private; unsigned long flags; + thin_put(tc); + wait_for_completion(&tc->can_destroy); + spin_lock_irqsave(&tc->pool->lock, flags); list_del_rcu(&tc->list); spin_unlock_irqrestore(&tc->pool->lock, flags); @@ -3192,6 +3253,9 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) mutex_unlock(&dm_thin_pool_table.mutex); + atomic_set(&tc->refcount, 1); + init_completion(&tc->can_destroy); + spin_lock_irqsave(&tc->pool->lock, flags); list_add_tail_rcu(&tc->list, &tc->pool->active_thins); spin_unlock_irqrestore(&tc->pool->lock, flags); From 87f7e41636ff201148443551d06bc74497160aac Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 8 Apr 2014 11:38:28 -0400 Subject: [PATCH 0039/1034] ext4: update PF_MEMALLOC handling in ext4_write_inode() The special handling of PF_MEMALLOC callers in ext4_write_inode() shouldn't be necessary as there shouldn't be any. Warn about it. Also update comment before the function as it seems somewhat outdated. (Changes modeled on an ext3 patch posted by Jan Kara to the linux-ext4 mailing list on Februaryt 28, 2014, which apparently never went into the ext3 tree.) Signed-off-by: "Theodore Ts'o" Cc: Jan Kara --- fs/ext4/inode.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 93f16c5e8a8e..7b93df9aa182 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4427,21 +4427,20 @@ out_brelse: * * We are called from a few places: * - * - Within generic_file_write() for O_SYNC files. + * - Within generic_file_aio_write() -> generic_write_sync() for O_SYNC files. * Here, there will be no transaction running. We wait for any running * transaction to commit. * - * - Within sys_sync(), kupdate and such. - * We wait on commit, if tol to. + * - Within flush work (sys_sync(), kupdate and such). + * We wait on commit, if told to. * - * - Within prune_icache() (PF_MEMALLOC == true) - * Here we simply return. We can't afford to block kswapd on the - * journal commit. + * - Within iput_final() -> write_inode_now() + * We wait on commit, if told to. * * In all cases it is actually safe for us to return without doing anything, * because the inode has been copied into a raw inode buffer in - * ext4_mark_inode_dirty(). This is a correctness thing for O_SYNC and for - * knfsd. + * ext4_mark_inode_dirty(). This is a correctness thing for WB_SYNC_ALL + * writeback. * * Note that we are absolutely dependent upon all inode dirtiers doing the * right thing: they *must* call mark_inode_dirty() after dirtying info in @@ -4453,15 +4452,15 @@ out_brelse: * stuff(); * inode->i_size = expr; * - * is in error because a kswapd-driven write_inode() could occur while - * `stuff()' is running, and the new i_size will be lost. Plus the inode - * will no longer be on the superblock's dirty inode list. + * is in error because write_inode() could occur while `stuff()' is running, + * and the new i_size will be lost. Plus the inode will no longer be on the + * superblock's dirty inode list. */ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) { int err; - if (current->flags & PF_MEMALLOC) + if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) return 0; if (EXT4_SB(inode->i_sb)->s_journal) { From cfe8255f0afcf5d2d1dbfa093223cafe38773fa7 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 10 Apr 2014 02:40:00 +0400 Subject: [PATCH 0040/1034] xtensa: xt2000: drop redundant sysmem initialization sysmem structure initialization in xt2000 platform_init is identical to the one done in init_arch just before the call to platform_init. Signed-off-by: Max Filippov --- arch/xtensa/platforms/xt2000/setup.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c index f9bc87966290..b90555cb8089 100644 --- a/arch/xtensa/platforms/xt2000/setup.c +++ b/arch/xtensa/platforms/xt2000/setup.c @@ -92,18 +92,8 @@ void __init platform_setup(char** cmdline) /* early initialization */ -extern sysmem_info_t __initdata sysmem; - -void platform_init(bp_tag_t* first) +void __init platform_init(bp_tag_t *first) { - /* Set default memory block if not provided by the bootloader. */ - - if (sysmem.nr_banks == 0) { - sysmem.nr_banks = 1; - sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; - sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START - + PLATFORM_DEFAULT_MEM_SIZE; - } } /* Heartbeat. Let the LED blink. */ From 390403fd79821bbd0c3a0d83307df2be87047b36 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 10 Apr 2014 11:01:09 -0700 Subject: [PATCH 0041/1034] ARM: OMAP3: PM: remove access to PRM_VOLTCTRL register There is a solitary write to this register every wakeup from off-mode, which isn't doing anything, so remove it. Also note that modifying this register trashes any attempted voltage scaling configuration and the change probably should never have gotten merged in the first place. Cc: Nishanth Menon Cc: Kevin Hilman Cc: Paul Walmsley Signed-off-by: Tero Kristo [tony@atomide.com: updated comments to describe regression] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm34xx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 1f3770a8a728..87099bb6de69 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -330,10 +330,6 @@ void omap_sram_idle(void) omap3_sram_restore_context(); omap2_sms_restore_context(); } - if (core_next_state == PWRDM_POWER_OFF) - omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, - OMAP3430_GR_MOD, - OMAP3_PRM_VOLTCTRL_OFFSET); } omap3_intc_resume_idle(); From 1ce01c4a199c50b023802be25261c0c02b2f0214 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 10 Apr 2014 22:58:20 -0400 Subject: [PATCH 0042/1034] ext4: fix COLLAPSE_RANGE test failure in data journalling mode When mounting ext4 with data=journal option, xfstest shared/002 and shared/004 are currently failing as checksum computed for testfile does not match with the checksum computed in other journal modes. In case of data=journal mode, a call to filemap_write_and_wait_range will not flush anything to disk as buffers are not marked dirty in write_end. In collapse range this call is followed by a call to truncate_pagecache_range. Due to this, when checksum is computed, a portion of file is re-read from disk which replace valid data with NULL bytes and hence the reason for the difference in checksum. Calling ext4_force_commit before filemap_write_and_wait_range solves the issue as it will mark the buffers dirty during commit transaction which can be later synced by a call to filemap_write_and_wait_range. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 82df3ce9874a..be1e56cbbf32 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5383,6 +5383,13 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb); punch_stop = (offset + len) >> EXT4_BLOCK_SIZE_BITS(sb); + /* Call ext4_force_commit to flush all data in case of data=journal. */ + if (ext4_should_journal_data(inode)) { + ret = ext4_force_commit(inode->i_sb); + if (ret) + return ret; + } + /* Write out all dirty pages */ ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1); if (ret) From c57ab39b9658315a742b6e61fdc86bb4d20cf566 Mon Sep 17 00:00:00 2001 From: Younger Liu Date: Thu, 10 Apr 2014 23:03:43 -0400 Subject: [PATCH 0043/1034] ext4: return ENOMEM rather than EIO when find_###_page() fails Return ENOMEM rather than EIO when find_get_page() fails in ext4_mb_get_buddy_page_lock() and find_or_create_page() fails in ext4_mb_load_buddy(). Signed-off-by: Younger Liu Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a888cac76e9c..73ccbb3b973b 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -989,7 +989,7 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb, poff = block % blocks_per_page; page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (!page) - return -EIO; + return -ENOMEM; BUG_ON(page->mapping != inode->i_mapping); e4b->bd_bitmap_page = page; e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize); @@ -1003,7 +1003,7 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb, pnum = block / blocks_per_page; page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (!page) - return -EIO; + return -ENOMEM; BUG_ON(page->mapping != inode->i_mapping); e4b->bd_buddy_page = page; return 0; @@ -1168,7 +1168,11 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) { + if (page == NULL) { + ret = -ENOMEM; + goto err; + } + if (!PageUptodate(page)) { ret = -EIO; goto err; } @@ -1197,7 +1201,11 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) { + if (page == NULL) { + ret = -ENOMEM; + goto err; + } + if (!PageUptodate(page)) { ret = -EIO; goto err; } From 622cad1325e404598fe3b148c3fa640dbaabc235 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Apr 2014 10:35:17 -0400 Subject: [PATCH 0044/1034] ext4: move ext4_update_i_disksize() into mpage_map_and_submit_extent() The function ext4_update_i_disksize() is used in only one place, in the function mpage_map_and_submit_extent(). Move its code to simplify the code paths, and also move the call to ext4_mark_inode_dirty() into the i_data_sem's critical region, to be consistent with all of the other places where we update i_disksize. That way, we also keep the raw_inode's i_disksize protected, to avoid the following race: CPU #1 CPU #2 down_write(&i_data_sem) Modify i_disk_size up_write(&i_data_sem) down_write(&i_data_sem) Modify i_disk_size Copy i_disk_size to on-disk inode up_write(&i_data_sem) Copy i_disk_size to on-disk inode Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: stable@vger.kernel.org --- fs/ext4/ext4.h | 17 ----------------- fs/ext4/inode.c | 14 ++++++++++++-- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f1c65dc7cc0a..66946aa62127 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2466,23 +2466,6 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize) up_write(&EXT4_I(inode)->i_data_sem); } -/* - * Update i_disksize after writeback has been started. Races with truncate - * are avoided by checking i_size under i_data_sem. - */ -static inline void ext4_wb_update_i_disksize(struct inode *inode, loff_t newsize) -{ - loff_t i_size; - - down_write(&EXT4_I(inode)->i_data_sem); - i_size = i_size_read(inode); - if (newsize > i_size) - newsize = i_size; - if (newsize > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = newsize; - up_write(&EXT4_I(inode)->i_data_sem); -} - struct ext4_group_info { unsigned long bb_state; struct rb_root bb_free_root; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7b93df9aa182..f023f0cb46fc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2247,13 +2247,23 @@ static int mpage_map_and_submit_extent(handle_t *handle, return err; } while (map->m_len); - /* Update on-disk size after IO is submitted */ + /* + * Update on-disk size after IO is submitted. Races with + * truncate are avoided by checking i_size under i_data_sem. + */ disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT; if (disksize > EXT4_I(inode)->i_disksize) { int err2; + loff_t i_size; - ext4_wb_update_i_disksize(inode, disksize); + down_write(&EXT4_I(inode)->i_data_sem); + i_size = i_size_read(inode); + if (disksize > i_size) + disksize = i_size; + if (disksize > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = disksize; err2 = ext4_mark_inode_dirty(handle, inode); + up_write(&EXT4_I(inode)->i_data_sem); if (err2) ext4_error(inode->i_sb, "Failed to mark inode %lu dirty", From c6c56697ae4bf1226263c19e8353343d7083f40e Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Apr 2014 10:18:17 +0300 Subject: [PATCH 0045/1034] ARM: OMAP3: hwmod data: Correct clock domains for USB modules OMAP3 doesn't contain "l3_init_clkdm" clock domain. Use the proper clock domains for USB Host and USB TLL modules. Gets rid of the following warnings during boot omap_hwmod: usb_host_hs: could not associate to clkdm l3_init_clkdm omap_hwmod: usb_tll_hs: could not associate to clkdm l3_init_clkdm Reported-by: Nishanth Menon Cc: Paul Walmsley Signed-off-by: Roger Quadros Fixes: de231388cb80a8ef3e779bbfa0564ba0157b7377 ("ARM: OMAP: USB: EHCI and OHCI hwmod structures for OMAP3") Cc: Keshava Munegowda Cc: Partha Basak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index a123ff0070bd..71ac7d5f3385 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1964,7 +1964,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { .name = "usb_host_hs", .class = &omap3xxx_usb_host_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "usbhost_clkdm", .mpu_irqs = omap3xxx_usb_host_hs_irqs, .main_clk = "usbhost_48m_fck", .prcm = { @@ -2047,7 +2047,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { .name = "usb_tll_hs", .class = &omap3xxx_usb_tll_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "core_l4_clkdm", .mpu_irqs = omap3xxx_usb_tll_hs_irqs, .main_clk = "usbtll_fck", .prcm = { From 8e4cb9aac2ada7f8a986606703c34e2d573bb876 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 24 Mar 2014 16:31:52 +0530 Subject: [PATCH 0046/1034] ARM: AM43xx: fix dpll init in bypass mode On AM43xx, if a PLL is in bypass at kernel init, the code in omap2_get_dpll_rate() will not realize this and will try to calculate the clock rate using the multiplier and the divider, resulting in errors. omap2_init_dpll_parent() has similar issue. Add the missing soc_is_am43xx() check to make the code work on AM43xx. Signed-off-by: Tomi Valkeinen Signed-off-by: Sathya Prakash M R Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt_dpll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index 2649ce445845..332af927f4d3 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -209,7 +209,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw) if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return 1; - } else if (soc_is_am33xx() || cpu_is_omap44xx()) { + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) @@ -255,7 +255,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return __clk_get_rate(dd->clk_bypass); - } else if (soc_is_am33xx() || cpu_is_omap44xx()) { + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) From 3d36ad7e7a9be0d130c862727a052ed279046437 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 14 Mar 2014 14:45:17 +0530 Subject: [PATCH 0047/1034] ARM: OMAP2+: hwmod: fix missing braces in _init() Bug was introduced by commit 'f92d959: ARM: OMAP2+: hwmod: Extract no-idle and no-reset info from DT' There were 2 versions of the patch posted which resulted in the above commit. While v1 [1] had the bug, v2 [2] had it fixed. However v1 apparently seemed to have been pulled in by mistake introducing the bug. Given of_find_property() does return NULL when the node passed is NULL, it did not introduce any functional issues as such, just the fact that the second if check was executed unnecessarily. [1] https://www.mail-archive.com/linux-omap@vger.kernel.org/msg94220.html [2] http://www.spinics.net/lists/linux-omap/msg98490.html Cc: Nishanth Menon Signed-off-by: Rajendra Nayak Signed-off-by: Suman Anna Signed-off-by: Lokesh Vutla Fixes: f92d9597f781f6a5a39c73dc71604bd8a21c5299 ("ARM: OMAP2+: hwmod: Extract no-idle and no-reset info from DT") Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 1f33f5db10d5..66c60fe1104c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2546,11 +2546,12 @@ static int __init _init(struct omap_hwmod *oh, void *data) return -EINVAL; } - if (np) + if (np) { if (of_find_property(np, "ti,no-reset-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_RESET; if (of_find_property(np, "ti,no-idle-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_IDLE; + } oh->_state = _HWMOD_STATE_INITIALIZED; From 9ef06cec7c96f6bf59f1dd8b64b9645820099051 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:47:00 -0400 Subject: [PATCH 0048/1034] ext4: remove unnecessary check for APPEND and IMMUTABLE All the checks IS_APPEND and IS_IMMUTABLE for the fallocate operation on the inode are done in vfs. No need to do this again in ext4. Remove it. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 6 ------ fs/ext4/inode.c | 6 +----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index be1e56cbbf32..ed4ec48239b6 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5398,12 +5398,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) /* Take mutex lock */ mutex_lock(&inode->i_mutex); - /* It's not possible punch hole on append only file */ - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { - ret = -EPERM; - goto out_mutex; - } - if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f023f0cb46fc..e2bba76f0d7b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3541,11 +3541,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) } mutex_lock(&inode->i_mutex); - /* It's not possible punch hole on append only file */ - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { - ret = -EPERM; - goto out_mutex; - } + if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; From 8fc61d92630d1c96057a94c61e1643475045b25b Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:51:34 -0400 Subject: [PATCH 0049/1034] fs: prevent doing FALLOC_FL_ZERO_RANGE on append only file Currently punch hole and collapse range fallocate operation are not allowed on append only file. This should be case for zero range as well. Fix it by allowing only pure fallocate (possibly with keep size set). Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/open.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/open.c b/fs/open.c index 631aea815def..3a83253d3373 100644 --- a/fs/open.c +++ b/fs/open.c @@ -254,11 +254,9 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) return -EBADF; /* - * It's not possible to punch hole or perform collapse range - * on append only file + * We can only allow pure fallocate on append only files */ - if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE) - && IS_APPEND(inode)) + if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode)) return -EPERM; if (IS_IMMUTABLE(inode)) From 23fffa925ea2c9a2bcb1a4453e2c542635aa3545 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:56:41 -0400 Subject: [PATCH 0050/1034] fs: move falloc collapse range check into the filesystem methods Currently in do_fallocate in collapse range case we're checking whether offset + len is not bigger than i_size. However there is nothing which would prevent i_size from changing so the check is pointless. It should be done in the file system itself and the file system needs to make sure that i_size is not going to change. The i_size check for the other fallocate modes are also done in the filesystems. As it is now we can easily crash the kernel by having two processes doing truncate and fallocate collapse range at the same time. This can be reproduced on ext4 and it is theoretically possible on xfs even though I was not able to trigger it with this simple test. This commit removes the check from do_fallocate and adds it to the file system. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Acked-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/ext4/extents.c | 11 +++++++++-- fs/open.c | 8 -------- fs/xfs/xfs_file.c | 10 +++++++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ed4ec48239b6..ac5460d0d133 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5368,8 +5368,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) loff_t new_size; int ret; - BUG_ON(offset + len > i_size_read(inode)); - /* Collapse range works only on fs block size aligned offsets. */ if (offset & (EXT4_BLOCK_SIZE(sb) - 1) || len & (EXT4_BLOCK_SIZE(sb) - 1)) @@ -5398,6 +5396,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) /* Take mutex lock */ mutex_lock(&inode->i_mutex); + /* + * There is no need to overlap collapse range with EOF, in which case + * it is effectively a truncate operation + */ + if (offset + len >= i_size_read(inode)) { + ret = -EINVAL; + goto out_mutex; + } + if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; diff --git a/fs/open.c b/fs/open.c index 3a83253d3373..adf34202213a 100644 --- a/fs/open.c +++ b/fs/open.c @@ -284,14 +284,6 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG; - /* - * There is no need to overlap collapse range with EOF, in which case - * it is effectively a truncate operation - */ - if ((mode & FALLOC_FL_COLLAPSE_RANGE) && - (offset + len >= i_size_read(inode))) - return -EINVAL; - if (!file->f_op->fallocate) return -EOPNOTSUPP; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f7abff8c16ca..3cb528c4f27c 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -840,7 +840,15 @@ xfs_file_fallocate( goto out_unlock; } - ASSERT(offset + len < i_size_read(inode)); + /* + * There is no need to overlap collapse range with EOF, + * in which case it is effectively a truncate operation + */ + if (offset + len >= i_size_read(inode)) { + error = -EINVAL; + goto out_unlock; + } + new_size = i_size_read(inode) - len; error = xfs_collapse_file_space(ip, offset, len); From 0790b31b69374ddadefebb156251b319e5b43345 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 10:05:37 -0400 Subject: [PATCH 0051/1034] fs: disallow all fallocate operation on active swapfile Currently some file system have IS_SWAPFILE check in their fallocate implementations and some do not. However we should really prevent any fallocate operation on swapfile so move the check to vfs and remove the redundant checks from the file systems fallocate implementations. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ceph/file.c | 3 --- fs/ext4/extents.c | 5 ----- fs/ext4/inode.c | 5 ----- fs/open.c | 7 +++++++ 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 09c7afe32e49..596e6cc9f9c4 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1215,9 +1215,6 @@ static long ceph_fallocate(struct file *file, int mode, if (!S_ISREG(inode->i_mode)) return -EOPNOTSUPP; - if (IS_SWAPFILE(inode)) - return -ETXTBSY; - mutex_lock(&inode->i_mutex); if (ceph_snap(inode) != CEPH_NOSNAP) { diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ac5460d0d133..b2d3869b5762 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5405,11 +5405,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) goto out_mutex; } - if (IS_SWAPFILE(inode)) { - ret = -ETXTBSY; - goto out_mutex; - } - /* Currently just for extent based files */ if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { ret = -EOPNOTSUPP; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e2bba76f0d7b..b74cfd2a42ec 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3542,11 +3542,6 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) mutex_lock(&inode->i_mutex); - if (IS_SWAPFILE(inode)) { - ret = -ETXTBSY; - goto out_mutex; - } - /* No need to punch hole beyond i_size */ if (offset >= inode->i_size) goto out_mutex; diff --git a/fs/open.c b/fs/open.c index adf34202213a..7b823daa6a93 100644 --- a/fs/open.c +++ b/fs/open.c @@ -262,6 +262,13 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (IS_IMMUTABLE(inode)) return -EPERM; + /* + * We can not allow to do any fallocate operation on an active + * swapfile + */ + if (IS_SWAPFILE(inode)) + ret = -ETXTBSY; + /* * Revalidate the write permissions, in case security policy has * changed since the files were opened. From 6e6358fc3c3c862bfe9a5bc029d3f8ce43dc9765 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 12 Apr 2014 12:45:25 -0400 Subject: [PATCH 0052/1034] ext4: use i_size_read in ext4_unaligned_aio() We haven't taken i_mutex yet, so we need to use i_size_read(). Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 6db7f7db7777..bc765591101a 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -82,7 +82,7 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, size_t count = iov_length(iov, nr_segs); loff_t final_size = pos + count; - if (pos >= inode->i_size) + if (pos >= i_size_read(inode)) return 0; if ((pos & blockmask) || (final_size & blockmask)) From 847c6c422aa0ae81a5517a9558ec2737806dca48 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Sat, 12 Apr 2014 12:45:55 -0400 Subject: [PATCH 0053/1034] ext4: fix byte order problems introduced by the COLLAPSE_RANGE patches This commit tries to fix some byte order issues that is found by sparse check. $ make M=fs/ext4 C=2 CF=-D__CHECK_ENDIAN__ ... CHECK fs/ext4/extents.c fs/ext4/extents.c:5232:41: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5236:52: warning: bad assignment (-=) to restricted __le32 fs/ext4/extents.c:5258:45: warning: bad assignment (-=) to restricted __le32 fs/ext4/extents.c:5303:28: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5318:18: warning: incorrect type in assignment (different base types) fs/ext4/extents.c:5318:18: expected unsigned int [unsigned] [usertype] ex_start fs/ext4/extents.c:5318:18: got restricted __le32 [usertype] ee_block fs/ext4/extents.c:5319:24: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5334:31: warning: incorrect type in assignment (different base types) ... Cc: Andreas Dilger Cc: Namjae Jeon Signed-off-by: Zheng Liu Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b2d3869b5762..f24ef8697609 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5229,11 +5229,11 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) update = 1; - *start = ex_last->ee_block + + *start = le32_to_cpu(ex_last->ee_block) + ext4_ext_get_actual_len(ex_last); while (ex_start <= ex_last) { - ex_start->ee_block -= shift; + le32_add_cpu(&ex_start->ee_block, -shift); if (ex_start > EXT_FIRST_EXTENT(path[depth].p_hdr)) { if (ext4_ext_try_to_merge_right(inode, @@ -5255,7 +5255,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, if (err) goto out; - path[depth].p_idx->ei_block -= shift; + le32_add_cpu(&path[depth].p_idx->ei_block, -shift); err = ext4_ext_dirty(handle, inode, path + depth); if (err) goto out; @@ -5300,7 +5300,8 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return ret; } - stop_block = extent->ee_block + ext4_ext_get_actual_len(extent); + stop_block = le32_to_cpu(extent->ee_block) + + ext4_ext_get_actual_len(extent); ext4_ext_drop_refs(path); kfree(path); @@ -5315,8 +5316,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, path = ext4_ext_find_extent(inode, start - 1, NULL, 0); depth = path->p_depth; extent = path[depth].p_ext; - ex_start = extent->ee_block; - ex_end = extent->ee_block + ext4_ext_get_actual_len(extent); + ex_start = le32_to_cpu(extent->ee_block); + ex_end = le32_to_cpu(extent->ee_block) + + ext4_ext_get_actual_len(extent); ext4_ext_drop_refs(path); kfree(path); @@ -5331,7 +5333,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; - current_block = extent->ee_block; + current_block = le32_to_cpu(extent->ee_block); if (start > current_block) { /* Hole, move to the next extent */ ret = mext_next_extent(inode, path, &extent); From 40c406c74eb9eed58ae7d4d12a0197f7279c9499 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 12 Apr 2014 22:53:53 -0400 Subject: [PATCH 0054/1034] ext4: COLLAPSE_RANGE only works on extent-based files Unfortunately, we weren't checking to make sure of this the inode was extent-based before attempt operate on it. Hilarity ensues. Signed-off-by: "Theodore Ts'o" Cc: Namjae Jeon --- fs/ext4/extents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f24ef8697609..96e0a4bc8faa 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4878,9 +4878,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (mode & FALLOC_FL_PUNCH_HOLE) return ext4_punch_hole(inode, offset, len); - if (mode & FALLOC_FL_COLLAPSE_RANGE) - return ext4_collapse_range(inode, offset, len); - ret = ext4_convert_inline_data(inode); if (ret) return ret; @@ -4892,6 +4889,9 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) return -EOPNOTSUPP; + if (mode & FALLOC_FL_COLLAPSE_RANGE) + return ext4_collapse_range(inode, offset, len); + if (mode & FALLOC_FL_ZERO_RANGE) return ext4_zero_range(file, offset, len, mode); From e2cbd587418251bb73c4c1e8e2c7c1816d7a98d9 Mon Sep 17 00:00:00 2001 From: jon ernst Date: Sat, 12 Apr 2014 23:01:28 -0400 Subject: [PATCH 0055/1034] ext4: silence sparse check warning for function ext4_trim_extent This fixes the following sparse warning: CHECK fs/ext4/mballoc.c fs/ext4/mballoc.c:5019:9: warning: context imbalance in 'ext4_trim_extent' - unexpected unlock Signed-off-by: "Jon Ernst" Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 73ccbb3b973b..c8238a26818c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5016,6 +5016,8 @@ error_return: */ static int ext4_trim_extent(struct super_block *sb, int start, int count, ext4_group_t group, struct ext4_buddy *e4b) +__releases(bitlock) +__acquires(bitlock) { struct ext4_free_extent ex; int ret = 0; From 8dc79ec4c0537e1b83c0739af82a7babefb30012 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Sun, 13 Apr 2014 15:05:42 -0400 Subject: [PATCH 0056/1034] ext4: fix error handling in ext4_ext_shift_extents Fix error handling by adding some. :-) Signed-off-by: Dmitry Monakhov Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 96e0a4bc8faa..38be06354b88 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5314,11 +5314,18 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, * enough to accomodate the shift. */ path = ext4_ext_find_extent(inode, start - 1, NULL, 0); + if (IS_ERR(path)) + return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; - ex_start = le32_to_cpu(extent->ee_block); - ex_end = le32_to_cpu(extent->ee_block) + + if (extent) { + ex_start = le32_to_cpu(extent->ee_block); + ex_end = le32_to_cpu(extent->ee_block) + ext4_ext_get_actual_len(extent); + } else { + ex_start = 0; + ex_end = 0; + } ext4_ext_drop_refs(path); kfree(path); From a18ed359bdddcded4f97ff5e2f07793ff9336913 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Sun, 13 Apr 2014 15:41:13 -0400 Subject: [PATCH 0057/1034] ext4: always check ext4_ext_find_extent result Where are some places where logic guaranties us that extent we are searching exits, but this may not be true due to on-disk data corruption. If such corruption happens we must prevent possible null pointer dereferences. Signed-off-by: Dmitry Monakhov Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 38be06354b88..64b400356cad 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3313,6 +3313,11 @@ static int ext4_split_extent(handle_t *handle, return PTR_ERR(path); depth = ext_depth(inode); ex = path[depth].p_ext; + if (!ex) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) map->m_lblk); + return -EIO; + } uninitialized = ext4_ext_is_uninitialized(ex); split_flag1 = 0; @@ -3694,6 +3699,12 @@ static int ext4_convert_initialized_extents(handle_t *handle, } depth = ext_depth(inode); ex = path[depth].p_ext; + if (!ex) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) map->m_lblk); + err = -EIO; + goto out; + } } err = ext4_ext_get_access(handle, inode, path + depth); @@ -5340,6 +5351,12 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; + if (!extent) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) start); + return -EIO; + } + current_block = le32_to_cpu(extent->ee_block); if (start > current_block) { /* Hole, move to the next extent */ From 07134a365f1c4be6e840a00ae452d1593f15c5fc Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 5 Mar 2014 14:25:50 +0100 Subject: [PATCH 0058/1034] ARM: dts: imx6: add PCIe interrupt mapping properties As defined by the common PCI bindings. Signed-off-by: Lucas Stach Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 55cb926fa3f7..e27408f5371f 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -10,6 +10,8 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include + #include "skeleton.dtsi" / { @@ -138,6 +140,12 @@ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */ num-lanes = <1>; interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>; clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi"; status = "disabled"; From 2b33319003bfd97decd9b4768ecfe70a6dfdba53 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 28 Mar 2014 02:09:13 -0300 Subject: [PATCH 0059/1034] ARM: dts: imx53-qsb-common: Fix memory region description On mx53qsb there are two DRAM chip selects: CS0 at 0x70000000 CS1 at 0xb0000000 Each bank has a 512MB DRAM, giving a total of 1GB of system DRAM. Fix the memory layout to describe the hardware appropriately. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-qsb-common.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi index 3f825a6813da..ede04fa4161f 100644 --- a/arch/arm/boot/dts/imx53-qsb-common.dtsi +++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi @@ -14,7 +14,8 @@ / { memory { - reg = <0x70000000 0x40000000>; + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; }; display0: display@di0 { From 8668d49896cc19354917ff67503e72f3f48ffaaa Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 28 Mar 2014 02:09:14 -0300 Subject: [PATCH 0060/1034] ARM: dts: imx53-m53evk: Fix memory region description On m53evk there are two DRAM chip selects: CS0 at 0x70000000 CS1 at 0xb0000000 Each bank has a 512MB DRAM, giving a total of 1GB of system DRAM. Fix the memory layout to describe the hardware appropriately. Signed-off-by: Fabio Estevam Acked-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-m53evk.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index f6d3ac3e5587..7fa2d1b5d60e 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -17,7 +17,8 @@ compatible = "denx,imx53-m53evk", "fsl,imx53"; memory { - reg = <0x70000000 0x20000000>; + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; }; soc { From 7b6b2f4bf76e72d0599bd0d4ca1c850f8308d50f Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 2 Apr 2014 19:05:37 +0200 Subject: [PATCH 0061/1034] ARM: dts: mx5: fix wrong stmpe-ts bindings Fix bindings for STMPE touchscreen controller to match the documented bindings and the actual bindings used by the driver. Signed-off-by: Stefan Agner Reviewed-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-m53evk.dts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index 7fa2d1b5d60e..d5d146a8b149 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -194,17 +194,17 @@ irq-trigger = <0x1>; stmpe_touchscreen { - compatible = "stmpe,ts"; + compatible = "st,stmpe-ts"; reg = <0>; - ts,sample-time = <4>; - ts,mod-12b = <1>; - ts,ref-sel = <0>; - ts,adc-freq = <1>; - ts,ave-ctrl = <3>; - ts,touch-det-delay = <3>; - ts,settling = <4>; - ts,fraction-z = <7>; - ts,i-drive = <1>; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <3>; + st,touch-det-delay = <3>; + st,settling = <4>; + st,fraction-z = <7>; + st,i-drive = <1>; }; }; From 54e8eaeec1227a024373e37315770cc79d69917b Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 28 Mar 2014 17:25:51 +0100 Subject: [PATCH 0062/1034] ARM: dts: imx: drop invalid size and address cells properties Those two properties should have been set to zero, which is the same as not specifying them. Having address-cells set to 1 causes OF interrupt mapping routines to add 1 to the interrupt-cells property and as result fail because all calculations are off by one. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 2 -- arch/arm/boot/dts/imx6sl.dtsi | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index e27408f5371f..2d04a5185fe9 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -48,8 +48,6 @@ intc: interrupt-controller@00a01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x00a01000 0x1000>, <0x00a00100 0x100>; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 3cb4941afeef..d92df0ab02e4 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -68,8 +68,6 @@ intc: interrupt-controller@00a01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x00a01000 0x1000>, <0x00a00100 0x100>; From c2bece3cb1215bdb68f2345f6a9b5d0b27c8724e Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 28 Mar 2014 17:52:52 +0100 Subject: [PATCH 0063/1034] ARM: imx6q-clk: parent lvds_gate from lvds_sel Allows fror proper refcounting of the parent clocks when enabling the clock output on CLK1/2 pads. Signed-off-by: Lucas Stach Reviewed-by: Marek Vasut Acked-by: Richard Zhu Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index b0e7f9d2c245..3ed67b592b48 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -208,8 +208,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) * the "output_enable" bit as a gate, even though it's really just * enabling clock output. */ - clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10); - clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11); + clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10); + clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11); /* name parent_name reg idx */ clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); From 2e3b9650561ae791ca0bd8c5f4868ef4df3cb842 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 Apr 2014 23:32:25 +0100 Subject: [PATCH 0064/1034] ARM: dt: microsom: don't set bit 7 for ethernet mux settings Bit 6,7 are marked as reserved for the ethernet RGMII pins, so avoid setting these bits. Signed-off-by: Russell King Signed-off-by: Shawn Guo --- .../arm/boot/dts/imx6qdl-microsom-ar8035.dtsi | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi index a3cb2fff8f61..d16066608e21 100644 --- a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi +++ b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi @@ -26,25 +26,25 @@ /* GPIO16 -> AR8035 25MHz */ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000 MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000 - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1 /* AR8035 pin strapping: IO voltage: pull up */ - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 /* AR8035 pin strapping: PHYADDR#0: pull down */ - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030 /* AR8035 pin strapping: PHYADDR#1: pull down */ - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030 /* AR8035 pin strapping: MODE#1: pull up */ - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 /* AR8035 pin strapping: MODE#3: pull up */ - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 /* AR8035 pin strapping: MODE#0: pull down */ - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030 /* * As the RMII pins are also connected to RGMII From 19f7cb6dec7408da8753bf3250098edab60cdbb6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:24 +0200 Subject: [PATCH 0065/1034] ARM: dts: imx6: edmqmx6: Fix usbotg id pin Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index a63bbb3d46bb..39ffa766384f 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -293,7 +293,7 @@ pinctrl_usbotg: usbotggrp { fsl,pins = < - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 >; }; From 465ca5dc4ad57b40ea632aabb32bf81a66632c4a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 7 Apr 2014 16:29:25 +0200 Subject: [PATCH 0066/1034] ARM: dts: imx6: edmqmx6: Do not use the OTG switch as VBUS regulator GPIO7_12 switches the D+/D- USB lines on and off. When we use this as VBUS regulator it means that USB device mode can never work as VBUS is never turned on in Device mode. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index 39ffa766384f..af32944cf9ae 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -40,13 +40,15 @@ regulator-always-on; }; - reg_usb_otg_vbus: regulator@1 { + reg_usb_otg_switch: regulator@1 { compatible = "regulator-fixed"; reg = <1>; - regulator-name = "usb_otg_vbus"; + regulator-name = "usb_otg_switch"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio7 12 0>; + regulator-boot-on; + regulator-always-on; }; reg_usb_host1: regulator@2 { @@ -348,7 +350,6 @@ }; &usbotg { - vbus-supply = <®_usb_otg_vbus>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg>; disable-over-current; From 8dde78e8d62ac5b5b8c07cd965928536c3556bc0 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:26 +0200 Subject: [PATCH 0067/1034] ARM: dts: imx6: edmqmx6: USB H1 only supports host mode Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index af32944cf9ae..e7762e456cbe 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -346,6 +346,7 @@ &usbh1 { vbus-supply = <®_usb_host1>; disable-over-current; + dr_mode = "host"; status = "okay"; }; From 52d13453df9aef536da6b93c7253fd618292a1cf Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:27 +0200 Subject: [PATCH 0068/1034] ARM: dts: imx6: edmqmx6: add second STMPE Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 38 +++++++++++++++++++------ 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index e7762e456cbe..e4ae38fd0269 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -19,7 +19,10 @@ compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q"; aliases { - gpio7 = &stmpe_gpio; + gpio7 = &stmpe_gpio1; + gpio8 = &stmpe_gpio2; + stmpe-i2c0 = &stmpe1; + stmpe-i2c1 = &stmpe2; }; memory { @@ -67,23 +70,23 @@ led-blue { label = "blue"; - gpios = <&stmpe_gpio 8 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; led-green { label = "green"; - gpios = <&stmpe_gpio 9 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>; }; led-pink { label = "pink"; - gpios = <&stmpe_gpio 10 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>; }; led-red { label = "red"; - gpios = <&stmpe_gpio 11 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>; }; }; }; @@ -101,7 +104,8 @@ clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2 - &pinctrl_stmpe>; + &pinctrl_stmpe1 + &pinctrl_stmpe2>; status = "okay"; pmic: pfuze100@08 { @@ -207,13 +211,25 @@ }; }; - stmpe: stmpe1601@40 { + stmpe1: stmpe1601@40 { compatible = "st,stmpe1601"; reg = <0x40>; interrupts = <30 0>; interrupt-parent = <&gpio3>; - stmpe_gpio: stmpe_gpio { + stmpe_gpio1: stmpe_gpio { + #gpio-cells = <2>; + compatible = "st,stmpe-gpio"; + }; + }; + + stmpe2: stmpe1601@44 { + compatible = "st,stmpe1601"; + reg = <0x44>; + interrupts = <2 0>; + interrupt-parent = <&gpio5>; + + stmpe_gpio2: stmpe_gpio { #gpio-cells = <2>; compatible = "st,stmpe-gpio"; }; @@ -275,10 +291,14 @@ >; }; - pinctrl_stmpe: stmpegrp { + pinctrl_stmpe1: stmpe1grp { fsl,pins = ; }; + pinctrl_stmpe2: stmpe2grp { + fsl,pins = ; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 From 0c658c48cbe952d2689211a09f456d7319e59b33 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 10 Apr 2014 15:14:14 +0800 Subject: [PATCH 0069/1034] ARM: dts: imx53-tx53: add IPU DI ports and endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the recent imx-drm device tree binding changes, we need to add IPU DI ports and endpoints for adapting. Signed-off-by: Shawn Guo Acked-by: Lothar Waßmann --- arch/arm/boot/dts/imx53-tx53-x03x.dts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts index 0217dde3b36b..3b73e81dc3f0 100644 --- a/arch/arm/boot/dts/imx53-tx53-x03x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts @@ -25,12 +25,17 @@ soc { display: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rgb24_vga1>; status = "okay"; + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; + display-timings { VGA { clock-frequency = <25200000>; @@ -293,6 +298,10 @@ }; }; +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + &kpp { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_kpp>; From 139412290de46a7d4ff3359c8989485840764572 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 10 Apr 2014 15:22:56 +0800 Subject: [PATCH 0070/1034] ARM: dts: imx6q-gw5xxx: remove dead 'crtcs' property Since commit (655b43c staging: imx-drm-core: Use OF graph to find components and connections between encoder and crtcs), 'crtcs' becomes a dead property. Remove it. Signed-off-by: Shawn Guo Acked-by: Tim Harvey --- arch/arm/boot/dts/imx6q-gw5400-a.dts | 3 --- arch/arm/boot/dts/imx6qdl-gw52xx.dtsi | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts index 902f98310481..e51bb3f0fd56 100644 --- a/arch/arm/boot/dts/imx6q-gw5400-a.dts +++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts @@ -487,9 +487,6 @@ &ldb { status = "okay"; - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; - }; }; &pcie { diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 8e99c9a9bc76..035d3a85c318 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -436,9 +436,6 @@ &ldb { status = "okay"; - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; }; &pcie { From fa1746ae3829ed8865a10a7fe3946ef91bddd458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Thu, 10 Apr 2014 10:03:40 +0200 Subject: [PATCH 0071/1034] ARM: dts: imx53: fix apparent copy/paste error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'remote-endpoint' property should point back to ipu_di1_lvds1 rather than ipu_di0_lvds0. Signed-off-by: Lothar Waßmann Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index b57ab57740f6..a99b64bfb046 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -430,7 +430,7 @@ port { lvds1_in: endpoint { - remote-endpoint = <&ipu_di0_lvds0>; + remote-endpoint = <&ipu_di1_lvds1>; }; }; }; From 2cd36711e2b9714c0bb500b4060714666f37ca2c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 11 Apr 2014 09:09:39 -0300 Subject: [PATCH 0072/1034] ARM: dts: imx6sl-evk: Add an entry for MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 In case the bootloader has incorrectly configured the ALT mode of MX6SL_PAD_ECSPI1_SS0 pad, we end up with the following probe error: m25p80 spi0.0: found mr25h256, expected m25p32 m25p80 spi0.0: mr25h256 (32 Kbytes) In order to avoid this issue, add an entry for MX6SL_PAD_ECSPI1_SS0 pad, so that kernel configures the ECSPI chip select as GPIO functionality, which results in correct SPI NOR probe. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6sl-evk.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index 864d8dfb51ca..a8d9a93fab85 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts @@ -282,6 +282,7 @@ MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1 MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1 MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1 + MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000 >; }; From 308965f94d00b670ca3a0f799839a68412da34d9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 11 Apr 2014 16:59:38 +0200 Subject: [PATCH 0073/1034] ARM: dts: vybrid: drop address and size cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Shawn Guo --- arch/arm/boot/dts/vf610.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 804873367669..bb78e901ed5d 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -72,8 +72,6 @@ intc: interrupt-controller@40002000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x40003000 0x1000>, <0x40002100 0x100>; From 4b2b404309f90e1ba12b0b187ca2490be19a22a6 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 11 Apr 2014 09:56:46 +0800 Subject: [PATCH 0074/1034] ARM: dts: imx: add required #clock-cells for fixed-clock Per bindings of fixed-clock, #clock-cells is a required property. Let's add it for those fixed rate clocks. Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx25.dtsi | 1 + arch/arm/boot/dts/imx27-apf27.dts | 1 + arch/arm/boot/dts/imx27.dtsi | 1 + arch/arm/boot/dts/imx50.dtsi | 4 ++++ arch/arm/boot/dts/imx51.dtsi | 4 ++++ arch/arm/boot/dts/imx53.dtsi | 4 ++++ arch/arm/boot/dts/imx6qdl.dtsi | 3 +++ arch/arm/boot/dts/imx6sl.dtsi | 2 ++ arch/arm/boot/dts/vf610-twr.dts | 2 ++ arch/arm/boot/dts/vf610.dtsi | 2 ++ 10 files changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 32f760e24898..ea323f09dc78 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -56,6 +56,7 @@ osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx27-apf27.dts b/arch/arm/boot/dts/imx27-apf27.dts index 09f57b39e3ef..73aae4f5e539 100644 --- a/arch/arm/boot/dts/imx27-apf27.dts +++ b/arch/arm/boot/dts/imx27-apf27.dts @@ -29,6 +29,7 @@ osc26m { compatible = "fsl,imx-osc26m", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; }; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 6279e0b4f768..137e010eab35 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -48,6 +48,7 @@ osc26m { compatible = "fsl,imx-osc26m", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <26000000>; }; }; diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi index 0c75fe3deb35..9c89d1ca97c2 100644 --- a/arch/arm/boot/dts/imx50.dtsi +++ b/arch/arm/boot/dts/imx50.dtsi @@ -53,21 +53,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <22579200>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 5f8216d08f6b..150bb4e2f744 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -50,21 +50,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index a99b64bfb046..9c2bff2252d0 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -70,21 +70,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <22579200>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 2d04a5185fe9..eca0971d4db1 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -59,16 +59,19 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index d92df0ab02e4..d26b099260a3 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -79,11 +79,13 @@ ckil { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; osc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 7dd1d6ede525..ded361075aab 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -25,11 +25,13 @@ clocks { audio_ext { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24576000>; }; enet_ext { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <50000000>; }; }; diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index bb78e901ed5d..b8ce0aa7b157 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -45,11 +45,13 @@ sxosc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; fxosc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; From edcf139081f501b1468ae6665217e8320d4c75e8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 12 Mar 2014 19:44:50 +0100 Subject: [PATCH 0075/1034] ARM: shmobile: r8a7791: Use rcar_gen2_read_mode_pins() helper Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7791.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index 701383fe3267..36e57508d879 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * MD EXTAL PLL0 PLL1 PLL3 @@ -43,8 +44,6 @@ * see "p1 / 2" on R8A7791_CLOCK_ROOT() below */ -#define MD(nr) (1 << nr) - #define CPG_BASE 0xe6150000 #define CPG_LEN 0x1000 @@ -68,7 +67,6 @@ #define MSTPSR9 IOMEM(0xe61509a4) #define MSTPSR11 IOMEM(0xe61509ac) -#define MODEMR 0xE6160060 #define SDCKCR 0xE6150074 #define SD1CKCR 0xE6150078 #define SD2CKCR 0xE615026c @@ -295,14 +293,9 @@ static struct clk_lookup lookups[] = { void __init r8a7791_clock_init(void) { - void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); - u32 mode; + u32 mode = rcar_gen2_read_mode_pins(); int k, ret = 0; - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - switch (mode & (MD(14) | MD(13))) { case 0: R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); From 25f5550f5a4b18fd77a2e719ba63cb34931ab66a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 13 Mar 2014 08:36:17 +0900 Subject: [PATCH 0076/1034] ARM: shmobile: Introduce shmobile_clk_workaround() Introduce a new clock workaround function used by DT reference code on the mach-shmobile subarchitecture. The new function shmobile_clk_workaround() is used to configure clkdev to allow DT and platform devices to coexist. It is possible for the DT reference board code to also request enabling of the clock in case the driver does not implement clock control. Signed-off-by: Magnus Damm [horms+renesas@verge.net.au: Removed trailing blank line] Reviewed-by: Wolfram Sang Tested-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 2 +- arch/arm/mach-shmobile/clock.c | 28 +++++++++++++++++++++ arch/arm/mach-shmobile/include/mach/clock.h | 16 ++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 4caffc912a81..c12a1c50e9d2 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -21,8 +21,8 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o # Clock objects -ifndef CONFIG_COMMON_CLK obj-y += clock.o +ifndef CONFIG_COMMON_CLK obj-$(CONFIG_ARCH_SH7372) += clock-sh7372.o obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index ad7df629d995..e7232a0373b9 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c @@ -21,6 +21,32 @@ */ #include #include + +#ifdef CONFIG_COMMON_CLK +#include +#include +#include + +void __init shmobile_clk_workaround(const struct clk_name *clks, + int nr_clks, bool enable) +{ + const struct clk_name *clkn; + struct clk *clk; + unsigned int i; + + for (i = 0; i < nr_clks; ++i) { + clkn = clks + i; + clk = clk_get(NULL, clkn->clk); + if (!IS_ERR(clk)) { + clk_register_clkdev(clk, clkn->con_id, clkn->dev_id); + if (enable) + clk_prepare_enable(clk); + clk_put(clk); + } + } +} + +#else /* CONFIG_COMMON_CLK */ #include #include #include @@ -58,3 +84,5 @@ void __clk_put(struct clk *clk) { } EXPORT_SYMBOL(__clk_put); + +#endif /* CONFIG_COMMON_CLK */ diff --git a/arch/arm/mach-shmobile/include/mach/clock.h b/arch/arm/mach-shmobile/include/mach/clock.h index 03e56074928c..9a93cf924b9c 100644 --- a/arch/arm/mach-shmobile/include/mach/clock.h +++ b/arch/arm/mach-shmobile/include/mach/clock.h @@ -1,6 +1,21 @@ #ifndef CLOCK_H #define CLOCK_H +#ifdef CONFIG_COMMON_CLK +/* temporary clock configuration helper for platform devices */ + +struct clk_name { + const char *clk; + const char *con_id; + const char *dev_id; +}; + +void shmobile_clk_workaround(const struct clk_name *clks, int nr_clks, + bool enable); + +#else /* CONFIG_COMMON_CLK */ +/* legacy clock implementation */ + unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk); extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops; @@ -36,4 +51,5 @@ do { \ (p)->div = d; \ } while (0) +#endif /* CONFIG_COMMON_CLK */ #endif From ab077bfdc4eaffa5328a9843d4d7970718ac0b8a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 1 Apr 2014 13:02:15 +0200 Subject: [PATCH 0077/1034] ARM: shmobile: r8a7790: Fix the I2C clocks parents in legacy code All I2C clocks derive from the HP clock, not from the P clock. Fix them. Signed-off-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7790.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 3f93503f5b96..331013995fe3 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -249,10 +249,10 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */ [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */ [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */ - [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ - [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ - [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ - [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ + [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ From 2b1b6e6865aeb236f759ad3f91db27b514e29023 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 1 Apr 2014 13:02:16 +0200 Subject: [PATCH 0078/1034] ARM: shmobile: r8a7791: Fix the I2C clocks parents in legacy code All I2C clocks derive from the HP clock, not from the P clock. Fix them. Signed-off-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7791.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index 36e57508d879..3b26c7eee873 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -188,12 +188,12 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */ [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */ [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */ - [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ - [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ - [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ - [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ - [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ - [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ + [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ + [MSTP927] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ + [MSTP925] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ From 79ea9934b8df700fa306c8ced2d3bbf94ff276a8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Apr 2014 16:31:46 +0200 Subject: [PATCH 0079/1034] ARM: shmobile: r8a7790: Rename VSP1_(SY|RT) clocks to VSP1_(S|R) The r8a7790 has four VSP1 instances, two of them being named VSPS (which stands for "VSP Standard") and VSPR (which stands for "VSP for Resizing"). The clock section in the SoC datasheet misunderstood the abbreviations as meaning VSP System and VSP Realtime, and named the corresponding clocks VSP1(SY) and VSP1(RT). This mistake has been carried over to the kernel code. Fix this by renaming the VSP1_SY and VSP1_RT clocks to VSP1_S and VSP1_R. Signed-off-by: Laurent Pinchart Acked-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 2 +- include/dt-bindings/clock/r8a7790-clock.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 618e5b537eaf..10b326bdf831 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -673,7 +673,7 @@ renesas,clock-indices = < R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 - R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY + R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S >; clock-output-names = "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h index 6548a5fbcf4a..9a7c4c5a35d1 100644 --- a/include/dt-bindings/clock/r8a7790-clock.h +++ b/include/dt-bindings/clock/r8a7790-clock.h @@ -33,8 +33,8 @@ #define R8A7790_CLK_TMU0 25 #define R8A7790_CLK_VSP1_DU1 27 #define R8A7790_CLK_VSP1_DU0 28 -#define R8A7790_CLK_VSP1_RT 30 -#define R8A7790_CLK_VSP1_SY 31 +#define R8A7790_CLK_VSP1_R 30 +#define R8A7790_CLK_VSP1_S 31 /* MSTP2 */ #define R8A7790_CLK_SCIFA2 2 From 58ea1d53ba93620ac50fef9d9720b2323971f243 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Apr 2014 16:31:47 +0200 Subject: [PATCH 0080/1034] ARM: shmobile: r8a7791: Rename VSP1_SY clocks to VSP1_S The r8a7791 has three VSP1 instances, one of them being named VSPS (which stands for "VSP Standard"). The clock section in the SoC datasheet misunderstood the abbreviation as meaning VSP System, and named the corresponding clock VSP1(SY). This mistake has been carried over to the kernel code. Fix this by renaming the VSP1_SY clock to VSP1_S. Signed-off-by: Laurent Pinchart Acked-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 2 +- include/dt-bindings/clock/r8a7791-clock.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 46181708e59c..aa1cba94196c 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -688,7 +688,7 @@ renesas,clock-indices = < R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 - R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY + R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_S >; clock-output-names = "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h index 30f82f286e29..f069bc6627cb 100644 --- a/include/dt-bindings/clock/r8a7791-clock.h +++ b/include/dt-bindings/clock/r8a7791-clock.h @@ -32,7 +32,7 @@ #define R8A7791_CLK_TMU0 25 #define R8A7791_CLK_VSP1_DU1 27 #define R8A7791_CLK_VSP1_DU0 28 -#define R8A7791_CLK_VSP1_SY 31 +#define R8A7791_CLK_VSP1_S 31 /* MSTP2 */ #define R8A7791_CLK_SCIFA2 2 From e6597e0e19bbabfdd1983dbe79892d8ba210a180 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 13 Mar 2014 08:36:26 +0900 Subject: [PATCH 0081/1034] ARM: shmobile: Use shmobile_clk_workaround() on Lager Convert the Lager DT reference code to use the newly introduced function shmobile_clk_workaround(). Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- .../arm/mach-shmobile/board-lager-reference.c | 65 +++++++------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 440aac36d693..c76248b9a5e7 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -18,12 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include #include #include #include +#include #include #include #include @@ -86,46 +85,32 @@ static void __init lager_add_du_device(void) platform_device_register_full(&info); } +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] = { + { "cmt0", NULL, "sh_cmt.0" }, + { "scifa0", NULL, "sh-sci.0" }, + { "scifa1", NULL, "sh-sci.1" }, + { "scifb0", NULL, "sh-sci.2" }, + { "scifb1", NULL, "sh-sci.3" }, + { "scifb2", NULL, "sh-sci.4" }, + { "scifa2", NULL, "sh-sci.5" }, + { "scif0", NULL, "sh-sci.6" }, + { "scif1", NULL, "sh-sci.7" }, + { "hscif0", NULL, "sh-sci.8" }, + { "hscif1", NULL, "sh-sci.9" }, + { "du0", "du.0", "rcar-du-r8a7790" }, + { "du1", "du.1", "rcar-du-r8a7790" }, + { "du2", "du.2", "rcar-du-r8a7790" }, + { "lvds0", "lvds.0", "rcar-du-r8a7790" }, + { "lvds1", "lvds.1", "rcar-du-r8a7790" }, +}; + static void __init lager_add_standard_devices(void) { - /* - * This is a really crude hack to provide clkdev support to platform - * devices until they get moved to DT. - */ - static const struct clk_name { - const char *clk; - const char *con_id; - const char *dev_id; - } clk_names[] = { - { "cmt0", NULL, "sh_cmt.0" }, - { "scifa0", NULL, "sh-sci.0" }, - { "scifa1", NULL, "sh-sci.1" }, - { "scifb0", NULL, "sh-sci.2" }, - { "scifb1", NULL, "sh-sci.3" }, - { "scifb2", NULL, "sh-sci.4" }, - { "scifa2", NULL, "sh-sci.5" }, - { "scif0", NULL, "sh-sci.6" }, - { "scif1", NULL, "sh-sci.7" }, - { "hscif0", NULL, "sh-sci.8" }, - { "hscif1", NULL, "sh-sci.9" }, - { "du0", "du.0", "rcar-du-r8a7790" }, - { "du1", "du.1", "rcar-du-r8a7790" }, - { "du2", "du.2", "rcar-du-r8a7790" }, - { "lvds0", "lvds.0", "rcar-du-r8a7790" }, - { "lvds1", "lvds.1", "rcar-du-r8a7790" }, - }; - struct clk *clk; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(clk_names); ++i) { - clk = clk_get(NULL, clk_names[i].clk); - if (!IS_ERR(clk)) { - clk_register_clkdev(clk, clk_names[i].con_id, - clk_names[i].dev_id); - clk_put(clk); - } - } - + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); r8a7790_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); From 89aff406dbc3ea3dfc008e8472181532c0c0f4ea Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 13 Mar 2014 08:36:35 +0900 Subject: [PATCH 0082/1034] ARM: shmobile: Use shmobile_clk_workaround() on Koelsch Convert the Koelsch DT reference code to use the newly introduced function shmobile_clk_workaround(). Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- .../mach-shmobile/board-koelsch-reference.c | 71 ++++++++----------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index a3fd30242bd8..a760f7f19bc9 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -19,12 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include #include #include #include +#include #include #include #include @@ -82,49 +81,35 @@ static void __init koelsch_add_du_device(void) platform_device_register_full(&info); } +/* + * This is a really crude hack to provide clkdev support to platform + * devices until they get moved to DT. + */ +static const struct clk_name clk_names[] = { + { "cmt0", NULL, "sh_cmt.0" }, + { "scifa0", NULL, "sh-sci.0" }, + { "scifa1", NULL, "sh-sci.1" }, + { "scifb0", NULL, "sh-sci.2" }, + { "scifb1", NULL, "sh-sci.3" }, + { "scifb2", NULL, "sh-sci.4" }, + { "scifa2", NULL, "sh-sci.5" }, + { "scif0", NULL, "sh-sci.6" }, + { "scif1", NULL, "sh-sci.7" }, + { "scif2", NULL, "sh-sci.8" }, + { "scif3", NULL, "sh-sci.9" }, + { "scif4", NULL, "sh-sci.10" }, + { "scif5", NULL, "sh-sci.11" }, + { "scifa3", NULL, "sh-sci.12" }, + { "scifa4", NULL, "sh-sci.13" }, + { "scifa5", NULL, "sh-sci.14" }, + { "du0", "du.0", "rcar-du-r8a7791" }, + { "du1", "du.1", "rcar-du-r8a7791" }, + { "lvds0", "lvds.0", "rcar-du-r8a7791" }, +}; + static void __init koelsch_add_standard_devices(void) { - /* - * This is a really crude hack to provide clkdev support to the CMT and - * DU devices until they get moved to DT. - */ - static const struct clk_name { - const char *clk; - const char *con_id; - const char *dev_id; - } clk_names[] = { - { "cmt0", NULL, "sh_cmt.0" }, - { "scifa0", NULL, "sh-sci.0" }, - { "scifa1", NULL, "sh-sci.1" }, - { "scifb0", NULL, "sh-sci.2" }, - { "scifb1", NULL, "sh-sci.3" }, - { "scifb2", NULL, "sh-sci.4" }, - { "scifa2", NULL, "sh-sci.5" }, - { "scif0", NULL, "sh-sci.6" }, - { "scif1", NULL, "sh-sci.7" }, - { "scif2", NULL, "sh-sci.8" }, - { "scif3", NULL, "sh-sci.9" }, - { "scif4", NULL, "sh-sci.10" }, - { "scif5", NULL, "sh-sci.11" }, - { "scifa3", NULL, "sh-sci.12" }, - { "scifa4", NULL, "sh-sci.13" }, - { "scifa5", NULL, "sh-sci.14" }, - { "du0", "du.0", "rcar-du-r8a7791" }, - { "du1", "du.1", "rcar-du-r8a7791" }, - { "lvds0", "lvds.0", "rcar-du-r8a7791" }, - }; - struct clk *clk; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(clk_names); ++i) { - clk = clk_get(NULL, clk_names[i].clk); - if (!IS_ERR(clk)) { - clk_register_clkdev(clk, clk_names[i].con_id, - clk_names[i].dev_id); - clk_put(clk); - } - } - + shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); r8a7791_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); From f6f98b3e44ea408e33eb4d695a4225cc11210cdb Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 13 Mar 2014 15:29:57 +0900 Subject: [PATCH 0083/1034] ARM: shmobile: koelsch: Annotate clk_names with __initconst Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/mach-shmobile/board-koelsch-reference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index a760f7f19bc9..1e6a4361c0eb 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -85,7 +85,7 @@ static void __init koelsch_add_du_device(void) * This is a really crude hack to provide clkdev support to platform * devices until they get moved to DT. */ -static const struct clk_name clk_names[] = { +static const struct clk_name clk_names[] __initconst = { { "cmt0", NULL, "sh_cmt.0" }, { "scifa0", NULL, "sh-sci.0" }, { "scifa1", NULL, "sh-sci.1" }, From f71c77286b2c1f809a85e8e42df88eb2ec132e5f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 13 Mar 2014 15:29:58 +0900 Subject: [PATCH 0084/1034] ARM: shmobile: lager: Annotate clk_names with __initconst Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/mach-shmobile/board-lager-reference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index c76248b9a5e7..7ff395efa9fe 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -89,7 +89,7 @@ static void __init lager_add_du_device(void) * This is a really crude hack to provide clkdev support to platform * devices until they get moved to DT. */ -static const struct clk_name clk_names[] = { +static const struct clk_name clk_names[] __initconst = { { "cmt0", NULL, "sh_cmt.0" }, { "scifa0", NULL, "sh-sci.0" }, { "scifa1", NULL, "sh-sci.1" }, From 53cf0cf7ba2ef785b339826a0765bb6b1756adeb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 13 Mar 2014 15:29:30 +0100 Subject: [PATCH 0085/1034] ARM: shmobile: koelsch-reference: Work around core clock issues Due to issues with runtime PM clock management, clocks not explicitly managed by their drivers may not be enabled at all, or be inadvertently disabled by the clk_disable_unused() late initcall. Until this is fixed, add a temporary workaround, calling shmobile_clk_workaround() with enable == true. For now this enables the clocks for: ether, i2c2, msiof0, qspi_mod, and thermal. More clocks can be added if needed. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-koelsch-reference.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index 1e6a4361c0eb..a39114a1fe1b 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -107,9 +107,21 @@ static const struct clk_name clk_names[] __initconst = { { "lvds0", "lvds.0", "rcar-du-r8a7791" }, }; +/* + * This is a really crude hack to work around core platform clock issues + */ +static const struct clk_name clk_enables[] = { + { "ether", NULL, "ee700000.ethernet" }, + { "i2c2", NULL, "e6530000.i2c" }, + { "msiof0", NULL, "e6e20000.spi" }, + { "qspi_mod", NULL, "e6b10000.spi" }, + { "thermal", NULL, "e61f0000.thermal" }, +}; + static void __init koelsch_add_standard_devices(void) { shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); + shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); r8a7791_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); From 9e7b83c221cc257f4dc37acc82bbcb80627c0ab9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 17 Mar 2014 11:19:56 +0900 Subject: [PATCH 0086/1034] ARM: shmobile: koelsch-reference: Annotate clk_enables as __initconst Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/mach-shmobile/board-koelsch-reference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index a39114a1fe1b..63117d52db9e 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -110,7 +110,7 @@ static const struct clk_name clk_names[] __initconst = { /* * This is a really crude hack to work around core platform clock issues */ -static const struct clk_name clk_enables[] = { +static const struct clk_name clk_enables[] __initconst = { { "ether", NULL, "ee700000.ethernet" }, { "i2c2", NULL, "e6530000.i2c" }, { "msiof0", NULL, "e6e20000.spi" }, From aa5de826afe747c353162bbc116c63ab5335f91c Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 17 Mar 2014 11:18:56 +0900 Subject: [PATCH 0087/1034] ARM: shmobile: lager-reference: Work around core clock issues Due to issues with runtime PM clock management, clocks not explicitly managed by their drivers may not be enabled at all, or be inadvertently disabled by the clk_disable_unused() late initcall. Until this is fixed, add a temporary workaround, calling shmobile_clk_workaround() with enable == true. For now this enables the clocks for: ether, msiof1, qspi_mod, and thermal. More clocks can be added if needed. Based on work for the koelsch board by Geert Uytterhoeven. Signed-off-by: Simon Horman Acked-by: Geert Uytterhoeven --- arch/arm/mach-shmobile/board-lager-reference.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 7ff395efa9fe..313118c5f365 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -108,9 +108,20 @@ static const struct clk_name clk_names[] __initconst = { { "lvds1", "lvds.1", "rcar-du-r8a7790" }, }; +/* + * This is a really crude hack to work around core platform clock issues + */ +static const struct clk_name clk_enables[] __initconst = { + { "ether", NULL, "ee700000.ethernet" }, + { "msiof1", NULL, "e6e10000.spi" }, + { "qspi_mod", NULL, "e6b10000.spi" }, + { "thermal", NULL, "e61f0000.thermal" }, +}; + static void __init lager_add_standard_devices(void) { shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); + shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); r8a7790_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); From f98b55d730492e664fb2649bd7054fec0fe81acd Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 18 Mar 2014 21:52:47 +0900 Subject: [PATCH 0088/1034] ARM: shmobile: Add Lager clock workarounds for SDHI and MMCIF Add MMCIF1, SDHI0 and SDHI2 to the clock workaround list for Lager multiplatform. Without these additional lines wakeup from Suspend-to-RAM never happens. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager-reference.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 313118c5f365..1eb48cffb4c5 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -114,7 +114,10 @@ static const struct clk_name clk_names[] __initconst = { static const struct clk_name clk_enables[] __initconst = { { "ether", NULL, "ee700000.ethernet" }, { "msiof1", NULL, "e6e10000.spi" }, + { "mmcif1", NULL, "ee220000.mmc" }, { "qspi_mod", NULL, "e6b10000.spi" }, + { "sdhi0", NULL, "ee100000.sd" }, + { "sdhi2", NULL, "ee140000.sd" }, { "thermal", NULL, "e61f0000.thermal" }, }; From f278ea78beeb17ea07d11fc3372d4f98c94dcf46 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 18 Mar 2014 21:54:34 +0900 Subject: [PATCH 0089/1034] ARM: shmobile: Add Koelsch clock workarounds for SDHI Add SDHI0, SDHI1 and SDHI2 to the clock workaround list for Koelsch multiplatform. Without these additional lines wakeup from Suspend-to-RAM never happens. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-koelsch-reference.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index 63117d52db9e..941f8b394e84 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -115,6 +115,9 @@ static const struct clk_name clk_enables[] __initconst = { { "i2c2", NULL, "e6530000.i2c" }, { "msiof0", NULL, "e6e20000.spi" }, { "qspi_mod", NULL, "e6b10000.spi" }, + { "sdhi0", NULL, "ee100000.sd" }, + { "sdhi1", NULL, "ee140000.sd" }, + { "sdhi2", NULL, "ee160000.sd" }, { "thermal", NULL, "e61f0000.thermal" }, }; From 9f85ff849c21b429c1e2137f2646f9cc667d8ded Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:59:34 -0700 Subject: [PATCH 0090/1034] ARM: shmobile: lager: fixup SND_SOC_DAIFMT_CBx_CFx flags e1508289404ab6ca28e0dc931612600f0441c417 (ASoC: rcar: fixup SND_SOC_DAIFMT_CBx_CFx flags) corrected SND_SOC_DAIFMT_CBx_CFx definition. But then, Lager board was maintenanced other branch. This patch correct SND_SOC_DAIFMT_CBx_CFx flag for lager Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index f0104bfe544e..18c7e0311aa6 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -588,14 +588,12 @@ static struct asoc_simple_card_info rsnd_card_info = { .card = "SSI01-AK4643", .codec = "ak4642-codec.2-0012", .platform = "rcar_sound", - .daifmt = SND_SOC_DAIFMT_LEFT_J, + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { .name = "rcar_sound", - .fmt = SND_SOC_DAIFMT_CBS_CFS, }, .codec_dai = { .name = "ak4642-hifi", - .fmt = SND_SOC_DAIFMT_CBM_CFM, .sysclk = 11289600, }, }; From 7b707277e734c553a8043e9b4d530eb47f4d60c8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:59:47 -0700 Subject: [PATCH 0091/1034] ARM: shmobile: armadillo800eva: fixup SND_SOC_DAIFMT_CBx_CFx flags c7a507eea1db1430476289f525f9c853d5d485e8 (ASoC: fsi: fixup SND_SOC_DAIFMT_CBx_CFx flags) exchanged sound flags, but armadillo800eva flags needs IB_NF. The recorded sound will be noise without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-armadillo800eva.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 2858f380beae..486063db2a2f 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -992,6 +992,7 @@ static struct asoc_simple_card_info fsi_wm8978_info = { .platform = "sh_fsi2", .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { + .fmt = SND_SOC_DAIFMT_IB_NF, .name = "fsia-dai", }, .codec_dai = { From a9d83bd6abc00e14e2db1660e2c7d889745bb3aa Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:56:42 -0700 Subject: [PATCH 0092/1034] ARM: shmobile: r8a7778: remove old style audio clock Current sound driver moves to new style clock, but is keeping compatiblity at this point. Move to new style on r8a7778 Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7778.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 2009a9bc6356..201fc487e4e1 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -175,10 +175,6 @@ static struct clk mstp_clks[MSTP_NR] = { static struct clk_lookup lookups[] = { /* main */ - CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), - CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), - CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), - CLKDEV_CON_ID("audio_clk_internal", &s1_clk), CLKDEV_CON_ID("shyway_clk", &s_clk), CLKDEV_CON_ID("peripheral_clk", &p_clk), @@ -234,15 +230,15 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), - CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP531]), - CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP530]), - CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP529]), - CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP528]), - CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP527]), - CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP526]), - CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP525]), - CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP524]), - CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP523]), + CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]), + CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]), + CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]), + CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]), + CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]), + CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]), + CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]), + CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]), + CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]), }; void __init r8a7778_clock_init(void) From 932616eed0308cbebbb20a079e4bed3674bf1117 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:56:50 -0700 Subject: [PATCH 0093/1034] ARM: shmobile: r8a7790: remove old style audio clock Current sound driver moves to new style clock, but is keeping compatiblity at this point. Move to new style on r8a7790 Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/clock-r8a7790.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 331013995fe3..a936ae7de083 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -294,10 +294,6 @@ static struct clk mstp_clks[MSTP_NR] = { static struct clk_lookup lookups[] = { /* main clocks */ - CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), - CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), - CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), - CLKDEV_CON_ID("audio_clk_internal", &m2_clk), CLKDEV_CON_ID("extal", &extal_clk), CLKDEV_CON_ID("extal_div2", &extal_div2_clk), CLKDEV_CON_ID("main", &main_clk), @@ -381,16 +377,16 @@ static struct clk_lookup lookups[] = { CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk), - CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP1031]), - CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP1030]), - CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP1029]), - CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP1028]), - CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP1027]), - CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP1026]), - CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP1025]), - CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP1024]), - CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP1023]), - CLKDEV_ICK_ID("scu.9", "rcar_sound", &mstp_clks[MSTP1022]), + CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]), + CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]), + CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]), + CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]), + CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]), + CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]), + CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]), + CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]), + CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]), + CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]), CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), From 115897dab004f580fc8b4c6bab057940ccb64989 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:56:57 -0700 Subject: [PATCH 0094/1034] ARM: shmobile: bockw: remove old style audio clock Current audio clock didn't have dependency to device/driver, but, it was not good design for DT support. To avoid branch merge conflict issue, it is using this load map, and this patch is 3) part. 1) add new style clock in platform 2) add new style clock method in driver 3) remove old tyle clock from platform Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-bockw.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index b4122f8cb8d9..1aca107f959f 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -591,6 +591,7 @@ static void __init bockw_init(void) { void __iomem *base; struct clk *clk; + struct platform_device *pdev; int i; r8a7778_clock_init(); @@ -673,9 +674,6 @@ static void __init bockw_init(void) } /* for Audio */ - clk = clk_get(NULL, "audio_clk_b"); - clk_set_rate(clk, 24576000); - clk_put(clk); rsnd_codec_power(5, 1); /* enable ak4642 */ platform_device_register_simple( @@ -684,11 +682,15 @@ static void __init bockw_init(void) platform_device_register_simple( "ak4554-adc-dac", 1, NULL, 0); - platform_device_register_resndata( + pdev = platform_device_register_resndata( &platform_bus, "rcar_sound", -1, rsnd_resources, ARRAY_SIZE(rsnd_resources), &rsnd_info, sizeof(rsnd_info)); + clk = clk_get(&pdev->dev, "clk_b"); + clk_set_rate(clk, 24576000); + clk_put(clk); + for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { struct platform_device_info cardinfo = { .parent = &platform_bus, From a3f50d1bdd47dfa07cb42f7d954739389664f166 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:57:05 -0700 Subject: [PATCH 0095/1034] ARM: shmobile: bockw: switch to use dai info for R-Car sound Now, R-Car sound driver supports dai info settings. switch to use it Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-bockw.c | 53 ++++++++++++++++++---------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 1aca107f959f..f444be2f241e 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -345,24 +345,39 @@ static struct rsnd_ssi_platform_info rsnd_ssi[] = { RSND_SSI_UNUSED, /* SSI 0 */ RSND_SSI_UNUSED, /* SSI 1 */ RSND_SSI_UNUSED, /* SSI 2 */ - RSND_SSI_SET(1, HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), RSND_SSI_PLAY), - RSND_SSI_SET(2, HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE), - RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), RSND_SSI_PLAY), - RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0), - RSND_SSI_SET(3, HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), RSND_SSI_PLAY), - RSND_SSI_SET(4, HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE), + RSND_SSI(HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE), + RSND_SSI(HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), 0), + RSND_SSI(HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE), }; -static struct rsnd_scu_platform_info rsnd_scu[9] = { - { .flags = 0, }, /* SRU 0 */ - { .flags = 0, }, /* SRU 1 */ - { .flags = 0, }, /* SRU 2 */ - { .flags = RSND_SCU_USE_HPBIF, }, - { .flags = RSND_SCU_USE_HPBIF, }, - { .flags = RSND_SCU_USE_HPBIF, }, - { .flags = RSND_SCU_USE_HPBIF, }, - { .flags = RSND_SCU_USE_HPBIF, }, - { .flags = RSND_SCU_USE_HPBIF, }, +static struct rsnd_src_platform_info rsnd_src[9] = { + RSND_SRC_UNUSED, /* SRU 0 */ + RSND_SRC_UNUSED, /* SRU 1 */ + RSND_SRC_UNUSED, /* SRU 2 */ + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), + RSND_SRC(0, 0), +}; + +static struct rsnd_dai_platform_info rsnd_dai[] = { + { + .playback = { .ssi = &rsnd_ssi[5], .src = &rsnd_src[5] }, + .capture = { .ssi = &rsnd_ssi[6], .src = &rsnd_src[6] }, + }, { + .playback = { .ssi = &rsnd_ssi[3], .src = &rsnd_src[3] }, + }, { + .capture = { .ssi = &rsnd_ssi[4], .src = &rsnd_src[4] }, + }, { + .playback = { .ssi = &rsnd_ssi[7], .src = &rsnd_src[7] }, + }, { + .capture = { .ssi = &rsnd_ssi[8], .src = &rsnd_src[8] }, + }, }; enum { @@ -437,8 +452,10 @@ static struct rcar_snd_info rsnd_info = { .flags = RSND_GEN1, .ssi_info = rsnd_ssi, .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), - .scu_info = rsnd_scu, - .scu_info_nr = ARRAY_SIZE(rsnd_scu), + .src_info = rsnd_src, + .src_info_nr = ARRAY_SIZE(rsnd_src), + .dai_info = rsnd_dai, + .dai_info_nr = ARRAY_SIZE(rsnd_dai), .start = rsnd_start, .stop = rsnd_stop, }; From 50f359d7389be354b46d781f3b234d3008d20f2f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:57:12 -0700 Subject: [PATCH 0096/1034] ARM: shmobile: lager: switch to use dai info for R-Car sound Now, R-Car sound driver supports dai info settings. switch to use it Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index f0104bfe544e..6af09e1e0841 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -567,20 +567,27 @@ static struct resource rsnd_resources[] __initdata = { }; static struct rsnd_ssi_platform_info rsnd_ssi[] = { - RSND_SSI_SET(0, 0, gic_spi(370), RSND_SSI_PLAY), - RSND_SSI_SET(0, 0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE), + RSND_SSI(0, gic_spi(370), 0), + RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE), }; -static struct rsnd_scu_platform_info rsnd_scu[2] = { +static struct rsnd_src_platform_info rsnd_src[2] = { /* no member at this point */ }; +static struct rsnd_dai_platform_info rsnd_dai = { + .playback = { .ssi = &rsnd_ssi[0], }, + .capture = { .ssi = &rsnd_ssi[1], }, +}; + static struct rcar_snd_info rsnd_info = { .flags = RSND_GEN2, .ssi_info = rsnd_ssi, .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), - .scu_info = rsnd_scu, - .scu_info_nr = ARRAY_SIZE(rsnd_scu), + .src_info = rsnd_src, + .src_info_nr = ARRAY_SIZE(rsnd_src), + .dai_info = &rsnd_dai, + .dai_info_nr = 1, }; static struct asoc_simple_card_info rsnd_card_info = { From b34f8624a7ddaca51a00d5bb35f55324e851b314 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Apr 2014 16:21:02 +0200 Subject: [PATCH 0097/1034] ARM: ux500: update defconfig Update the ux500 defconfig to match the latest output of savedefconfig. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 65f77885c167..d130a01d9342 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -1,6 +1,6 @@ # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y +CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y @@ -10,7 +10,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y -CONFIG_MACH_UX500_DT=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y @@ -85,8 +84,6 @@ CONFIG_AB8500_USB=y CONFIG_USB_GADGET=y CONFIG_USB_ETH=m CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y From ccc3e2a463e25ccbbd6cc4dcfff23b8c81c669dc Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 26 Mar 2014 14:19:07 +0100 Subject: [PATCH 0098/1034] ARM: ux500: u8500_defconfig: Enable PARTITION_ADVANCED There are both (e)MMC/SD-card support in ux500, thus it's reasonable to support partitions for block devices as default. While updating the defconfig, we rebase it towards Kconfig changes. Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index d130a01d9342..dac0a876e737 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -7,6 +7,7 @@ CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y @@ -36,6 +37,8 @@ CONFIG_PHONET=y # CONFIG_WIRELESS is not set CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_SENSORS_BH1780=y @@ -107,8 +110,6 @@ CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_MISC_FILESYSTEMS is not set From f661e7733f8c45692147ea52a16c9c1856cf152b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 26 Mar 2014 14:30:53 +0100 Subject: [PATCH 0099/1034] ARM: u300: u300_defconfig: Enable PARTITION_ADVANCED Since there are SD-card support in u300, it's reasonable to support partitions for block devices as default. While updating the defconfig, we rebase it towards Kconfig changes. Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/configs/u300_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index fd81a1b99cce..aaa95ab606a8 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -11,6 +11,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_U300=y @@ -21,7 +22,6 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072" CONFIG_CPU_IDLE=y -CONFIG_FPE_NWFPE=y # CONFIG_SUSPEND is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set @@ -64,8 +64,8 @@ CONFIG_TMPFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_INFO=y From 7c60a6ed10e7d7146fbae52a7f5d59c05169ce4d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Apr 2014 16:31:53 +0200 Subject: [PATCH 0100/1034] ARM: ux500: configure in sensors This enables the STMicroelectronics MEMS sensors for accelerometer, gyroscope, magnetometer and pressure that are mounted on the Ux500 models. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index dac0a876e737..726b1fa786f7 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -103,6 +103,11 @@ CONFIG_STE_DMA40=y CONFIG_STAGING=y CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y CONFIG_HSEM_U8500=y +CONFIG_IIO=y +CONFIG_IIO_ST_ACCEL_3AXIS=y +CONFIG_IIO_ST_GYRO_3AXIS=y +CONFIG_IIO_ST_MAGN_3AXIS=y +CONFIG_IIO_ST_PRESS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y From 7633fb959b711a8d91548911eb087fb931c7b8e4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 13:20:38 +0200 Subject: [PATCH 0101/1034] gpio: set data first, then chip and handler During irq mapping, in irq_set_chip_and_handler() the process of setting this up may incur calls to lock the irqchip, which in turn may need to dereference and use the chip data. So set the data first, then set the chip and handler. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 761013f8b82f..f48817d97480 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1387,8 +1387,8 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, { struct gpio_chip *chip = d->host_data; - irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); irq_set_chip_data(irq, chip); + irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else From e9595f84a6273dffc5b75564d9b12a77630c529e Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 31 Mar 2014 15:16:49 +0300 Subject: [PATCH 0102/1034] gpio / ACPI: Don't crash on NULL chip->dev Commit aa92b6f689ac (gpio / ACPI: Allocate ACPI specific data directly in acpi_gpiochip_add()) moved ACPI handle checking to acpi_gpiochip_add() but forgot to check whether chip->dev is NULL before dereferencing it. Since chip->dev pointer is optional we can end up with crash like following: BUG: unable to handle kernel NULL pointer dereference at 00000138 IP: [] acpi_gpiochip_add+0x13/0x190 *pde = 00000000 Oops: 0000 [#1] PREEMPT SMP Modules linked in: ssb(+) ... CPU: 0 PID: 512 Comm: modprobe Tainted: G W 3.14.0-rc7-next-20140324-t1 #24 Hardware name: Dell Inc. Latitude D830 /0UY141, BIOS A02 06/07/2007 task: f5799900 ti: f543e000 task.ti: f543e000 EIP: 0060:[] EFLAGS: 00010282 CPU: 0 EIP is at acpi_gpiochip_add+0x13/0x190 EAX: 00000000 EBX: f57824c4 ECX: 00000000 EDX: 00000000 ESI: f57824c4 EDI: 00000010 EBP: f543fc54 ESP: f543fc40 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 8005003b CR2: 00000138 CR3: 355f8000 CR4: 000007d0 Stack: f543fc5c fd1f7790 f57824c4 000000be 00000010 f543fc84 c1269f4e f543fc74 fd1f78bd 00008002 f57822b0 f5782090 fd1f8400 00000286 fd1f9994 00000000 f5782000 f543fc8c fd1f7e39 f543fcc8 fd1f0bd8 000000c0 00000000 00000000 Call Trace: [] ? ssb_pcie_mdio_write+0xa0/0xd0 [ssb] [] gpiochip_add+0xee/0x300 [] ? ssb_pcicore_serdes_workaround+0xfd/0x140 [ssb] [] ssb_gpio_init+0x89/0xa0 [ssb] [] ssb_attach_queued_buses+0xc8/0x2d0 [ssb] [] ssb_bus_register+0x185/0x1f0 [ssb] [] ? ssb_pci_xtal+0x220/0x220 [ssb] [] ssb_bus_pcibus_register+0x2c/0x80 [ssb] [] ssb_pcihost_probe+0x9c/0x110 [ssb] [] pci_device_probe+0x6f/0xc0 [] ? sysfs_create_link+0x25/0x40 [] driver_probe_device+0x79/0x360 [] ? pci_match_device+0xb2/0xc0 [] __driver_attach+0x71/0x80 [] ? __device_attach+0x40/0x40 [] bus_for_each_dev+0x47/0x80 [] driver_attach+0x1e/0x20 [] ? __device_attach+0x40/0x40 [] bus_add_driver+0x157/0x230 [] driver_register+0x59/0xe0 ... Fix this by checking chip->dev pointer against NULL first. Also we can now remove redundant check in acpi_gpiochip_request/free_interrupts(). Reported-by: Sabrina Dubroca Signed-off-by: Mika Westerberg Tested-by: Sabrina Dubroca Acked-by: Alexandre Courbot Tested-by: Josh Boyer Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index bf0f8b476696..d5be56fe689e 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -233,7 +233,7 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio) { struct gpio_chip *chip = acpi_gpio->chip; - if (!chip->dev || !chip->to_irq) + if (!chip->to_irq) return; INIT_LIST_HEAD(&acpi_gpio->events); @@ -253,7 +253,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio) struct acpi_gpio_event *event, *ep; struct gpio_chip *chip = acpi_gpio->chip; - if (!chip->dev || !chip->to_irq) + if (!chip->to_irq) return; list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) { @@ -501,6 +501,9 @@ void acpi_gpiochip_add(struct gpio_chip *chip) acpi_handle handle; acpi_status status; + if (!chip || !chip->dev) + return; + handle = ACPI_HANDLE(chip->dev); if (!handle) return; @@ -531,6 +534,9 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) acpi_handle handle; acpi_status status; + if (!chip || !chip->dev) + return; + handle = ACPI_HANDLE(chip->dev); if (!handle) return; From b5539fa2d59d697b7b8e28b4d08da844ff60f7cf Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 1 Apr 2014 13:03:00 +0300 Subject: [PATCH 0103/1034] gpio / ACPI: Prevent potential wrap of GPIO value on OpRegion read Dan Carpenter's static code checker reports: The patch 473ed7be0da0: "gpio / ACPI: Add support for ACPI GPIO operation regions" from Mar 14, 2014, leads to the following static checker warning: drivers/gpio/gpiolib-acpi.c:454 acpi_gpio_adr_space_handler() warn: should 'gpiod_get_raw_value(desc) << i' be a 64 bit type? This is due the fact that *value is of type u64 and gpiod_get_raw_value() returns int. Since i can be larger than 31, it is possible that the value returned gets wrapped. Fix this by casting the return of gpiod_get_raw_value() to u64 first before shift. Reported-by: Dan Carpenter Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d5be56fe689e..401add28933f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -451,7 +451,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, if (function == ACPI_WRITE) gpiod_set_raw_value(desc, !!((1 << i) & *value)); else - *value |= gpiod_get_raw_value(desc) << i; + *value |= (u64)gpiod_get_raw_value(desc) << i; } out: From 1fb4e407b520a2344b92a680c75672c7900aedf8 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Apr 2014 11:08:26 +0200 Subject: [PATCH 0104/1034] ARM: ux500: configure for CW1200 WLAN chip The CW1200 WLAN chip driver had been in the kernel for a while, we only need to activate it for the Ux500 properly. The latter require some elaborative work, but in the meantime, let's make sure we atleast compile it in. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 726b1fa786f7..d219d6a43238 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -34,7 +34,10 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NETFILTER=y CONFIG_PHONET=y -# CONFIG_WIRELESS is not set +CONFIG_CFG80211=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y @@ -45,7 +48,8 @@ CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y CONFIG_SMSC911X=y CONFIG_SMSC_PHY=y -# CONFIG_WLAN is not set +CONFIG_CW1200=y +CONFIG_CW1200_WLAN_SDIO=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -93,7 +97,6 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_LM3530=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_LP5521=y -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AB8500=y From 9374f375ab8b91a394487ef0707d827dcdeb8139 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Sat, 5 Apr 2014 12:11:48 +0100 Subject: [PATCH 0105/1034] ASoC: wm5110: Add in OSR controls for OUT5/6 There are no OSR controls on outputs 1-4 on wm5110, however when these were removed the ones on output 5 and 6 were also accidentally removed, but those actually exist. This patch adds these controls back in. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..83a7e2f91ece 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -367,6 +367,11 @@ SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL, SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL, ARIZONA_HP3_SC_ENA_SHIFT, 1, 0), +SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, + ARIZONA_OUT5_OSR_SHIFT, 1, 0), +SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L, + ARIZONA_OUT6_OSR_SHIFT, 1, 0), + SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, From a39f75f7907fa3a708751dc283e3ab3e7da526b8 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:23 +0800 Subject: [PATCH 0106/1034] ASoC: core: Move the default regmap I/O setting to snd_soc_register_codec() Add the default regmap I/O setting to snd_soc_register_codec() while the CODEC is initialising, which will be called by CODEC driver device probe(), and then we can make XXX_set_cache_io() go away entirely from each CODEC ASoC probe. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 28 ++++++++++++++++++---------- sound/soc/soc-io.c | 9 +++------ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..2f62436026d2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -754,6 +754,7 @@ struct snd_soc_codec_driver { unsigned int freq_in, unsigned int freq_out); /* codec IO */ + struct regmap *(*get_regmap)(struct device *); unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); int (*display_register)(struct snd_soc_codec *, char *, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..5071a3a0ac83 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1137,16 +1137,6 @@ static int soc_probe_codec(struct snd_soc_card *card, codec->dapm.idle_bias_off = driver->idle_bias_off; - if (!codec->write && dev_get_regmap(codec->dev, NULL)) { - /* Set the default I/O up try regmap */ - ret = snd_soc_codec_set_cache_io(codec, NULL); - if (ret < 0) { - dev_err(codec->dev, - "Failed to set cache I/O: %d\n", ret); - goto err_probe; - } - } - if (driver->probe) { ret = driver->probe(codec); if (ret < 0) { @@ -4263,6 +4253,7 @@ int snd_soc_register_codec(struct device *dev, int num_dai) { struct snd_soc_codec *codec; + struct regmap *regmap; int ret, i; dev_dbg(dev, "codec register %s\n", dev_name(dev)); @@ -4294,6 +4285,23 @@ int snd_soc_register_codec(struct device *dev, codec->num_dai = num_dai; mutex_init(&codec->mutex); + if (!codec->write) { + if (codec_drv->get_regmap) + regmap = codec_drv->get_regmap(dev); + else + regmap = dev_get_regmap(dev, NULL); + + if (regmap) { + ret = snd_soc_codec_set_cache_io(codec, regmap); + if (ret && ret != -ENOTSUPP) { + dev_err(codec->dev, + "Failed to set cache I/O:%d\n", + ret); + return ret; + } + } + } + for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); fixup_codec_formats(&dai_drv[i].capture); diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 260efc8466fc..6480e8f29310 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -60,14 +60,11 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, { int ret; - /* Device has made its own regmap arrangements */ if (!regmap) - codec->control_data = dev_get_regmap(codec->dev, NULL); - else - codec->control_data = regmap; + return -EINVAL; - if (IS_ERR(codec->control_data)) - return PTR_ERR(codec->control_data); + /* Device has made its own regmap arrangements */ + codec->control_data = regmap; codec->write = hw_write; codec->read = hw_read; From bbc0bd7fd3f671096625b5cbde97e12e3e2dba8f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:24 +0800 Subject: [PATCH 0107/1034] ASoC: 88pm860x: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b07e17160f94..dc9e6b94e645 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1327,10 +1327,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) pm860x->codec = codec; - ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap); - if (ret) - return ret; - for (i = 0; i < 4; i++) { ret = request_threaded_irq(pm860x->irq[i], NULL, pm860x_codec_handler, IRQF_ONESHOT, @@ -1362,10 +1358,18 @@ static int pm860x_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *pm860x_get_regmap(struct device *dev) +{ + struct pm860x_priv *pm860x = dev_get_drvdata(dev); + + return pm860x->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_pm860x = { .probe = pm860x_probe, .remove = pm860x_remove, .set_bias_level = pm860x_set_bias_level, + .get_regmap = pm860x_get_regmap, .controls = pm860x_snd_controls, .num_controls = ARRAY_SIZE(pm860x_snd_controls), From 49101a25acd69cf36192888392c518a299c091af Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:25 +0800 Subject: [PATCH 0108/1034] ASoC: cq93vc: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/cq93vc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1e25c7af853b..5e5518d20311 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -139,8 +139,6 @@ static int cq93vc_probe(struct snd_soc_codec *codec) davinci_vc->cq93vc.codec = codec; - snd_soc_codec_set_cache_io(codec, davinci_vc->regmap); - /* Off, with power on */ cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -154,11 +152,19 @@ static int cq93vc_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *cq93vc_get_regmap(struct device *dev) +{ + struct davinci_vc *davinci_vc = codec->dev->platform_data; + + return davinci_vc->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { .set_bias_level = cq93vc_set_bias_level, .probe = cq93vc_probe, .remove = cq93vc_remove, .resume = cq93vc_resume, + .get_regmap = cq93vc_get_regmap, .controls = cq93vc_snd_controls, .num_controls = ARRAY_SIZE(cq93vc_snd_controls), }; From d957f1651ed2976e18c75c5644a92ed471c3ae9e Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:26 +0800 Subject: [PATCH 0109/1034] ASoC: mc13783: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2c59b1fb69dc..8c0cec392dec 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -608,14 +608,6 @@ static struct snd_kcontrol_new mc13783_control_list[] = { static int mc13783_probe(struct snd_soc_codec *codec) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = snd_soc_codec_set_cache_io(codec, - dev_get_regmap(codec->dev->parent, NULL)); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } /* these are the reset values */ mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); @@ -735,9 +727,15 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { } }; +struct regmap *mc13783_get_regmap(struct device *dev) +{ + return dev_get_regmap(dev->parent, NULL); +} + static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { .probe = mc13783_probe, .remove = mc13783_remove, + .get_regmap = mc13783_get_regmap, .controls = mc13783_control_list, .num_controls = ARRAY_SIZE(mc13783_control_list), .dapm_widgets = mc13783_dapm_widgets, From 83905ef3cbd0025830e9db65bf5ce7db721e39a7 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:27 +0800 Subject: [PATCH 0110/1034] ASoC: si476x: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Andrey Smirnov Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 244c097cd905..961b7e8ac0da 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -208,13 +208,6 @@ out: return err; } -static int si476x_codec_probe(struct snd_soc_codec *codec) -{ - struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL); - - return snd_soc_codec_set_cache_io(codec, regmap); -} - static struct snd_soc_dai_ops si476x_dai_ops = { .hw_params = si476x_codec_hw_params, .set_fmt = si476x_codec_set_dai_fmt, @@ -238,8 +231,13 @@ static struct snd_soc_dai_driver si476x_dai = { .ops = &si476x_dai_ops, }; +struct regmap *si476x_get_regmap(struct device *dev) +{ + return dev_get_regmap(dev->parent, NULL); +} + static struct snd_soc_codec_driver soc_codec_dev_si476x = { - .probe = si476x_codec_probe, + .get_regmap = si476x_get_regmap, .dapm_widgets = si476x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), .dapm_routes = si476x_dapm_routes, From c8b02acd45e4b30aef2a86526e6844071cfd41bf Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:28 +0800 Subject: [PATCH 0111/1034] ASoC: wm5102: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index dcf1d12cfef8..aa60ba23b017 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1760,10 +1760,6 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; - ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); if (ret != 0) return ret; @@ -1802,9 +1798,17 @@ static unsigned int wm5102_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; +struct regmap *wm5102_get_regmap(struct device *dev) +{ + struct wm5102_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { .probe = wm5102_codec_probe, .remove = wm5102_codec_remove, + .get_regmap = wm5102_get_regmap, .idle_bias_off = true, From 6e4842d30c2eea928b6df6adfe9db49ec971f32d Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:29 +0800 Subject: [PATCH 0112/1034] ASoC: wm5110: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..4be5f990a9d6 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1589,10 +1589,6 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) priv->core.arizona->dapm = &codec->dapm; - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; - arizona_init_spk(codec); arizona_init_gpio(codec); @@ -1633,9 +1629,17 @@ static unsigned int wm5110_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_6R, }; +struct regmap *wm5110_get_regmap(struct device *dev) +{ + struct wm5110_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { .probe = wm5110_codec_probe, .remove = wm5110_codec_remove, + .get_regmap = wm5110_get_regmap, .idle_bias_off = true, From aec0eb50e5f71f6c28cc0a4739b34ec109fe1a56 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:30 +0800 Subject: [PATCH 0113/1034] ASoC: wm8350: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 757256bf7672..6b31a9f83137 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1505,8 +1505,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - snd_soc_codec_set_cache_io(codec, wm8350->regmap); - /* Put the codec into reset if it wasn't already */ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1608,11 +1606,19 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8350_get_regmap(struct device *dev) +{ + struct wm8350 *wm8350 = dev_get_platdata(dev); + + return wm8350->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .probe = wm8350_codec_probe, .remove = wm8350_codec_remove, .suspend = wm8350_suspend, .resume = wm8350_resume, + .get_regmap = wm8350_get_regmap, .set_bias_level = wm8350_set_bias_level, .controls = wm8350_snd_controls, From 4504badea3a3edd0d114b51a866cd98b4ff626b0 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:31 +0800 Subject: [PATCH 0114/1034] ASoC: wm8400: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8400.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 146564feaea0..e6410f2e8cac 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1318,8 +1318,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) priv->wm8400 = wm8400; priv->codec = codec; - snd_soc_codec_set_cache_io(codec, wm8400->regmap); - ret = devm_regulator_bulk_get(wm8400->dev, ARRAY_SIZE(power), &power[0]); if (ret != 0) { @@ -1361,11 +1359,19 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8400_get_regmap(struct device *dev) +{ + struct wm8400 *wm8400 = dev_get_platdata(dev); + + return wm8400->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { .probe = wm8400_codec_probe, .remove = wm8400_codec_remove, .suspend = wm8400_suspend, .resume = wm8400_resume, + .get_regmap = wm8400_get_regmap, .set_bias_level = wm8400_set_bias_level, .controls = wm8400_snd_controls, From c0b6f59b7036c0cb7e0d03240fcb095104855ab9 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:32 +0800 Subject: [PATCH 0115/1034] ASoC: wm8994: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..daa4edcfe14a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3999,8 +3999,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.codec = codec; - snd_soc_codec_set_cache_io(codec, control->regmap); - mutex_init(&wm8994->accdet_lock); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); @@ -4434,11 +4432,19 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8994_get_regmap(struct device *dev) +{ + struct wm8994 *control = dev_get_drvdata(dev->parent); + + return control->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .probe = wm8994_codec_probe, .remove = wm8994_codec_remove, .suspend = wm8994_codec_suspend, .resume = wm8994_codec_resume, + .get_regmap = wm8994_get_regmap, .set_bias_level = wm8994_set_bias_level, }; From 964eafb1d59b7c270982d144882c64b93c67eb03 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:33 +0800 Subject: [PATCH 0116/1034] ASoC: wm8997: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 004186b6bd48..3d50621b070c 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1051,11 +1051,6 @@ static struct snd_soc_dai_driver wm8997_dai[] = { static int wm8997_codec_probe(struct snd_soc_codec *codec) { struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; arizona_init_spk(codec); @@ -1086,9 +1081,17 @@ static unsigned int wm8997_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; +struct regmap *wm8997_get_regmap(struct device *dev) +{ + struct wm8997_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { .probe = wm8997_codec_probe, .remove = wm8997_codec_remove, + .get_regmap = wm8997_get_regmap, .idle_bias_off = true, From 7a34b1c1dff720dd8dcf63e2b0e5fc15a8f7208f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 3 Apr 2014 07:53:59 +0800 Subject: [PATCH 0117/1034] ASoC: codec: fix the sparse check warnings. Some thing Likes: reproduce: make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> sound/soc/codecs/wm8997.c:1084:15: sparse: symbol \ 'wm8997_get_regmap' was not declared. Should it be static? Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 2 +- sound/soc/codecs/cq93vc.c | 2 +- sound/soc/codecs/mc13783.c | 2 +- sound/soc/codecs/si476x.c | 2 +- sound/soc/codecs/wm5102.c | 2 +- sound/soc/codecs/wm5110.c | 2 +- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8400.c | 2 +- sound/soc/codecs/wm8994.c | 2 +- sound/soc/codecs/wm8997.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index dc9e6b94e645..f073b6feac94 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1358,7 +1358,7 @@ static int pm860x_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *pm860x_get_regmap(struct device *dev) +static struct regmap *pm860x_get_regmap(struct device *dev) { struct pm860x_priv *pm860x = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 5e5518d20311..5ee48c8e4849 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -152,7 +152,7 @@ static int cq93vc_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *cq93vc_get_regmap(struct device *dev) +static struct regmap *cq93vc_get_regmap(struct device *dev) { struct davinci_vc *davinci_vc = codec->dev->platform_data; diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 8c0cec392dec..9029e20514e1 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -727,7 +727,7 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { } }; -struct regmap *mc13783_get_regmap(struct device *dev) +static struct regmap *mc13783_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 961b7e8ac0da..f26befb0c297 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -231,7 +231,7 @@ static struct snd_soc_dai_driver si476x_dai = { .ops = &si476x_dai_ops, }; -struct regmap *si476x_get_regmap(struct device *dev) +static struct regmap *si476x_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index aa60ba23b017..7a046536ea68 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1798,7 +1798,7 @@ static unsigned int wm5102_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; -struct regmap *wm5102_get_regmap(struct device *dev) +static struct regmap *wm5102_get_regmap(struct device *dev) { struct wm5102_priv *priv = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4be5f990a9d6..97eb1bc5bea7 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1629,7 +1629,7 @@ static unsigned int wm5110_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_6R, }; -struct regmap *wm5110_get_regmap(struct device *dev) +static struct regmap *wm5110_get_regmap(struct device *dev) { struct wm5110_priv *priv = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 6b31a9f83137..1bd14b64a6c0 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1606,7 +1606,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8350_get_regmap(struct device *dev) +static struct regmap *wm8350_get_regmap(struct device *dev) { struct wm8350 *wm8350 = dev_get_platdata(dev); diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index e6410f2e8cac..5880d223e161 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1359,7 +1359,7 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8400_get_regmap(struct device *dev) +static struct regmap *wm8400_get_regmap(struct device *dev) { struct wm8400 *wm8400 = dev_get_platdata(dev); diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index daa4edcfe14a..6f336da856c5 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4432,7 +4432,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8994_get_regmap(struct device *dev) +static struct regmap *wm8994_get_regmap(struct device *dev) { struct wm8994 *control = dev_get_drvdata(dev->parent); diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 3d50621b070c..09c4150840a3 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1081,7 +1081,7 @@ static unsigned int wm8997_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; -struct regmap *wm8997_get_regmap(struct device *dev) +static struct regmap *wm8997_get_regmap(struct device *dev) { struct wm8997_priv *priv = dev_get_drvdata(dev); From ea53bf77d147e7e560ac007fdaa30fb98c37c712 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:04 +0100 Subject: [PATCH 0118/1034] ASoC: Add snd_soc_kcontrol_codec() helper function For CODEC controls snd_kcontrol_chip() currently returns a pointer to the CODEC that registered the control. With the upcoming consolidation of platform and CODEC controls this will change. Prepare for this by introducing the snd_soc_kcontrol_codec() helper function that will hide the implementation details of how the CODEC for a control can be obtained. This will allow us to change this easily in the future. The patch also updates all CODEC drivers to use the new helper function. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- include/sound/soc.h | 14 ++++++++++++++ sound/soc/codecs/88pm860x-codec.c | 8 ++++---- sound/soc/codecs/ab8500-codec.c | 12 ++++++------ sound/soc/codecs/adav80x.c | 4 ++-- sound/soc/codecs/ak4641.c | 4 ++-- sound/soc/codecs/cs4270.c | 2 +- sound/soc/codecs/cs4271.c | 4 ++-- sound/soc/codecs/cs42l51.c | 4 ++-- sound/soc/codecs/da7210.c | 4 ++-- sound/soc/codecs/da7213.c | 4 ++-- sound/soc/codecs/da732x.c | 4 ++-- sound/soc/codecs/da9055.c | 2 +- sound/soc/codecs/lm4857.c | 4 ++-- sound/soc/codecs/max9768.c | 4 ++-- sound/soc/codecs/max98088.c | 12 ++++++------ sound/soc/codecs/max98090.c | 4 ++-- sound/soc/codecs/max98095.c | 16 ++++++++-------- sound/soc/codecs/pcm1681.c | 4 ++-- sound/soc/codecs/rt5631.c | 4 ++-- sound/soc/codecs/sgtl5000.c | 4 ++-- sound/soc/codecs/sta32x.c | 4 ++-- sound/soc/codecs/tas5086.c | 4 ++-- sound/soc/codecs/tlv320aic23.c | 4 ++-- sound/soc/codecs/tlv320dac33.c | 4 ++-- sound/soc/codecs/twl4030.c | 10 +++++----- sound/soc/codecs/twl6040.c | 8 ++++---- sound/soc/codecs/wl1273.c | 12 ++++++------ sound/soc/codecs/wm2000.c | 8 ++++---- sound/soc/codecs/wm8350.c | 4 ++-- sound/soc/codecs/wm8400.c | 2 +- sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8731.c | 4 ++-- sound/soc/codecs/wm8753.c | 4 ++-- sound/soc/codecs/wm8804.c | 4 ++-- sound/soc/codecs/wm8903.c | 4 ++-- sound/soc/codecs/wm8904.c | 14 +++++++------- sound/soc/codecs/wm8955.c | 4 ++-- sound/soc/codecs/wm8958-dsp2.c | 32 +++++++++++++++---------------- sound/soc/codecs/wm8960.c | 4 ++-- sound/soc/codecs/wm8962.c | 8 ++++---- sound/soc/codecs/wm8983.c | 4 ++-- sound/soc/codecs/wm8985.c | 4 ++-- sound/soc/codecs/wm8990.c | 2 +- sound/soc/codecs/wm8991.c | 2 +- sound/soc/codecs/wm8994.c | 10 +++++----- sound/soc/codecs/wm8996.c | 4 ++-- sound/soc/codecs/wm9081.c | 4 ++-- sound/soc/codecs/wm_adsp.c | 4 ++-- sound/soc/codecs/wm_hubs.c | 2 +- 49 files changed, 154 insertions(+), 140 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..e150030b754d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1228,6 +1228,20 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec) return snd_soc_component_is_active(&codec->component); } +/** + * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control + * @kcontrol: The control for which to get the CODEC + * + * Note: This function will only work correctly if the control has been + * registered with snd_soc_add_codec_controls() or via table based setup of + * snd_soc_codec_driver. Otherwise the behavior is undefined. + */ +static inline struct snd_soc_codec *snd_soc_kcontrol_codec( + struct snd_kcontrol *kcontrol) +{ + return snd_kcontrol_chip(kcontrol); +} + int snd_soc_util_init(void); void snd_soc_util_exit(void); diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b07e17160f94..b18cafa5a858 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -276,7 +276,7 @@ static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; int val[2], val2[2], i; @@ -300,7 +300,7 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; int err; @@ -333,7 +333,7 @@ static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -353,7 +353,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 1ad92cbf0b24..1fb4402bf72d 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -1139,7 +1139,7 @@ static void anc_configure(struct snd_soc_codec *codec, static int sid_status_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); mutex_lock(&codec->mutex); @@ -1153,7 +1153,7 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol, static int sid_status_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); unsigned int param, sidconf, val; int status = 1; @@ -1208,7 +1208,7 @@ out: static int anc_status_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); mutex_lock(&codec->mutex); @@ -1221,7 +1221,7 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol, static int anc_status_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); struct device *dev = codec->dev; bool apply_fir, apply_iir; @@ -1306,7 +1306,7 @@ static int filter_control_info(struct snd_kcontrol *kcontrol, static int filter_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; @@ -1322,7 +1322,7 @@ static int filter_control_get(struct snd_kcontrol *kcontrol, static int filter_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 5062e34ee8dc..cf170b5ef426 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -315,7 +315,7 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec) static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int deemph = ucontrol->value.enumerated.item[0]; @@ -330,7 +330,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = adav80x->deemph; diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 868c0e2da1ec..7afe8f482088 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -74,7 +74,7 @@ static int ak4641_set_deemph(struct snd_soc_codec *codec) static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; @@ -89,7 +89,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = ak4641->deemph; diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 3920e6264948..9947a9583679 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -438,7 +438,7 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); int left = !ucontrol->value.integer.value[0]; int right = !ucontrol->value.integer.value[1]; diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index aef4965750c7..93cec52f4733 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -284,7 +284,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec) static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = cs4271->deemph; @@ -294,7 +294,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); cs4271->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..23acaa0263dc 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -55,7 +55,7 @@ struct cs42l51_private { static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3; switch (value) { @@ -83,7 +83,7 @@ static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned char val; switch (ucontrol->value.integer.value[0]) { diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 137e8ebc092c..21810e5f3321 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -335,7 +335,7 @@ static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel, static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); if (ucontrol->value.integer.value[0]) { /* Check if noise suppression is enabled */ @@ -358,7 +358,7 @@ static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u8 val; if (ucontrol->value.integer.value[0]) { diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 738fa18a50d2..9ec577f0edb4 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -345,7 +345,7 @@ static void da7213_alc_calib(struct snd_soc_codec *codec) static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); int ret; @@ -361,7 +361,7 @@ static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); /* Force ALC offset calibration if enabling ALC */ diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 48f3fef68484..2fae31cb0067 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -332,7 +332,7 @@ static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum, static int da732x_hpf_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; unsigned int reg = enum_ctrl->reg; unsigned int sel = ucontrol->value.integer.value[0]; @@ -360,7 +360,7 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol, static int da732x_hpf_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; unsigned int reg = enum_ctrl->reg; int val; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 4ff06b50fbba..ad19cc56702b 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -484,7 +484,7 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u8 reg_val, adc_left, adc_right, mic_left, mic_right; int avg_left_data, avg_right_data, offset_l, offset_r; diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 4f048db9f55f..a924bb9d7886 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -49,7 +49,7 @@ static const struct reg_default lm4857_default_regs[] = { static int lm4857_get_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = lm4857->mode; @@ -60,7 +60,7 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol, static int lm4857_set_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); uint8_t value = ucontrol->value.integer.value[0]; diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index ec481fc428c7..e1c196a41930 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -43,7 +43,7 @@ static struct reg_default max9768_default_regs[] = { static int max9768_get_gpio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); int val = gpio_get_value_cansleep(max9768->mute_gpio); @@ -55,7 +55,7 @@ static int max9768_get_gpio(struct snd_kcontrol *kcontrol, static int max9768_set_gpio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ef7cf89f5623..9134982807b5 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -635,7 +635,7 @@ static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum, static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -649,7 +649,7 @@ static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98088->mic1pre; @@ -659,7 +659,7 @@ static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -673,7 +673,7 @@ static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98088->mic2pre; @@ -1750,7 +1750,7 @@ static void max98088_setup_eq2(struct snd_soc_codec *codec) static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); struct max98088_pdata *pdata = max98088->pdata; int channel = max98088_get_channel(codec, kcontrol->id.name); @@ -1782,7 +1782,7 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); int channel = max98088_get_channel(codec, kcontrol->id.name); struct max98088_cdata *cdata; diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..49d12387ac2f 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -426,7 +426,7 @@ static const unsigned int max98090_rcv_lout_tlv[] = { static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -466,7 +466,7 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 03f0536e6f61..5d4c621dbf99 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -612,7 +612,7 @@ static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum, static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -626,7 +626,7 @@ static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98095->mic1pre; @@ -636,7 +636,7 @@ static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -650,7 +650,7 @@ static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98095->mic2pre; @@ -1737,7 +1737,7 @@ static int max98095_get_eq_channel(const char *name) static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct max98095_pdata *pdata = max98095->pdata; int channel = max98095_get_eq_channel(kcontrol->id.name); @@ -1801,7 +1801,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); int channel = max98095_get_eq_channel(kcontrol->id.name); struct max98095_cdata *cdata; @@ -1891,7 +1891,7 @@ static int max98095_get_bq_channel(struct snd_soc_codec *codec, static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct max98095_pdata *pdata = max98095->pdata; int channel = max98095_get_bq_channel(codec, kcontrol->id.name); @@ -1952,7 +1952,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); int channel = max98095_get_bq_channel(codec, kcontrol->id.name); struct max98095_cdata *cdata; diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index e427544183d7..a722a023c262 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -115,7 +115,7 @@ static int pcm1681_set_deemph(struct snd_soc_codec *codec) static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->deemph; @@ -126,7 +126,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); priv->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index d4c229f0233f..30e234708579 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -188,7 +188,7 @@ static unsigned int mic_bst_tlv[] = { static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = rt5631->dmic_used_flag; @@ -199,7 +199,7 @@ static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); rt5631->dmic_used_flag = ucontrol->value.integer.value[0]; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index d3ed1be5a186..b56caefcf664 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -296,7 +296,7 @@ static int dac_info_volsw(struct snd_kcontrol *kcontrol, static int dac_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg; int l; int r; @@ -349,7 +349,7 @@ static int dac_get_volsw(struct snd_kcontrol *kcontrol, static int dac_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg; int l; int r; diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 12577749b17b..0579d187135b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -243,7 +243,7 @@ static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol, static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; unsigned int cfud; @@ -272,7 +272,7 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index a895a5e4bdf2..d48491a4a19d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -272,7 +272,7 @@ static int tas5086_set_deemph(struct snd_soc_codec *codec) static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->deemph; @@ -283,7 +283,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); priv->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 20864ee8793b..686b8b85b956 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -82,7 +82,7 @@ static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0); static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u16 val, reg; val = (ucontrol->value.integer.value[0] & 0x07); @@ -105,7 +105,7 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u16 val; val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0); diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 6bfc8a17331b..517055ab65ef 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -442,7 +442,7 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w, static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = dac33->fifo_mode; @@ -453,7 +453,7 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); int ret = 0; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 975e0f760ac1..69e12a311ba2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -830,7 +830,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; @@ -859,7 +859,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; @@ -888,7 +888,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -915,7 +915,7 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -956,7 +956,7 @@ static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum, static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); if (twl4030->configured) { diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index bd3a20647fdf..0f6067f04e29 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -484,7 +484,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->hs_power_mode; @@ -495,7 +495,7 @@ static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int high_perf = ucontrol->value.enumerated.item[0]; int ret = 0; @@ -512,7 +512,7 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->pll_power_mode; @@ -523,7 +523,7 @@ static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); priv->pll_power_mode = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 6be5f80b65f1..4ead0dc02b87 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -172,7 +172,7 @@ out: static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wl1273->mode; @@ -190,7 +190,7 @@ static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); if (wl1273->mode == ucontrol->value.integer.value[0]) @@ -214,7 +214,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: enter.\n", __func__); @@ -227,7 +227,7 @@ static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); int val, r = 0; @@ -251,7 +251,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: enter.\n", __func__); @@ -264,7 +264,7 @@ static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); int r; diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 83a2c872925c..a4c352cc3464 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -607,7 +607,7 @@ static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->anc_active; @@ -618,7 +618,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int anc_active = ucontrol->value.enumerated.item[0]; int ret; @@ -640,7 +640,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->spk_ena; @@ -651,7 +651,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int val = ucontrol->value.enumerated.item[0]; int ret; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 757256bf7672..42a72b2404d5 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -302,7 +302,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out = NULL; struct soc_mixer_control *mc = @@ -345,7 +345,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out1 = &wm8350_priv->out1; struct wm8350_output *out2 = &wm8350_priv->out2; diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 146564feaea0..edfdbcd9d316 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -93,7 +93,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index af7ed8b5d4e1..7665ff6aea6d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -252,7 +252,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index d74f43975b90..763b265d9528 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -119,7 +119,7 @@ static int wm8731_set_deemph(struct snd_soc_codec *codec) static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8731->deemph; @@ -130,7 +130,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; int ret = 0; diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index cbb8d55052a4..53e57b4049a8 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -234,7 +234,7 @@ SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase), static int wm8753_get_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8753->dai_func; @@ -244,7 +244,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol, static int wm8753_set_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); u16 ioctl; diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index ee76f0fb4299..589455c3bfcd 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -106,7 +106,7 @@ static int txsrc_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); src = snd_soc_read(codec, WM8804_SPDTX4); if (src & 0x40) ucontrol->value.integer.value[0] = 1; @@ -122,7 +122,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src, txpwr; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); if (ucontrol->value.integer.value[0] != 0 && ucontrol->value.integer.value[0] != 1) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b0084a127d18..b84940c359a1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -439,7 +439,7 @@ static int wm8903_set_deemph(struct snd_soc_codec *codec) static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8903->deemph; @@ -450,7 +450,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; int ret = 0; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 49c35c36935e..f7c549949c54 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -391,7 +391,7 @@ static void wm8904_set_drc(struct snd_soc_codec *codec) static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; int value = ucontrol->value.integer.value[0]; @@ -409,7 +409,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; @@ -462,7 +462,7 @@ static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; int value = ucontrol->value.integer.value[0]; @@ -480,7 +480,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; @@ -520,7 +520,7 @@ static int wm8904_set_deemph(struct snd_soc_codec *codec) static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->deemph; @@ -530,7 +530,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; @@ -570,7 +570,7 @@ static SOC_ENUM_SINGLE_DECL(hpf_mode, WM8904_ADC_DIGITAL_0, 5, static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int val; int ret; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index fecd4e4f4c57..7e443c4f6f85 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -390,7 +390,7 @@ static int wm8955_set_deemph(struct snd_soc_codec *codec) static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8955->deemph; @@ -400,7 +400,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 7ac2e511403c..b2ebb104d879 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -456,7 +456,7 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -478,7 +478,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; @@ -500,7 +500,7 @@ static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int mbc = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; @@ -512,7 +512,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int mbc = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) @@ -546,7 +546,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -568,7 +568,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; @@ -579,7 +579,7 @@ static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -601,7 +601,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; @@ -623,7 +623,7 @@ static int wm8958_vss_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int vss = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; @@ -635,7 +635,7 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int vss = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) @@ -684,7 +684,7 @@ static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int hpf = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (hpf < 3) @@ -699,7 +699,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int hpf = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (hpf < 3) { @@ -746,7 +746,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -768,7 +768,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; @@ -790,7 +790,7 @@ static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int eq = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; @@ -802,7 +802,7 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int eq = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d04e9cad445c..a145d0431b63 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -178,7 +178,7 @@ static int wm8960_set_deemph(struct snd_soc_codec *codec) static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8960->deemph; @@ -188,7 +188,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 5522d2566c67..37986c84cbff 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1552,7 +1552,7 @@ static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int shift = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift); @@ -1564,7 +1564,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int shift = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); int old = wm8962->dsp2_ena; int ret = 0; @@ -1602,7 +1602,7 @@ out: static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int ret; /* Apply the update (if any) */ @@ -1632,7 +1632,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int ret; /* Apply the update (if any) */ diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 2b9bfa53efbf..19d5baa38f5c 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -552,7 +552,7 @@ static const struct snd_soc_dapm_route wm8983_audio_map[] = { static int eqmode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); @@ -567,7 +567,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, static int eqmode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int regpwr2, regpwr3; unsigned int reg_eq; diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 5473dc969585..ad23ffb8346c 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -526,7 +526,7 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { static int eqmode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); @@ -541,7 +541,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, static int eqmode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int regpwr2, regpwr3; unsigned int reg_eq; diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c413c1991453..b5c1f0f07058 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -132,7 +132,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 844cc4a60d66..b8fd284fc0c0 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -154,7 +154,7 @@ static const unsigned int out_sidetone_tlv[] = { static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg = kcontrol->private_value & 0xff; int ret; u16 val; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..3eb390be7dee 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -298,7 +298,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int mask, ret; /* Can't enable both ADC and DAC paths simultaneously */ @@ -355,7 +355,7 @@ static int wm8994_get_drc(const char *name) static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; @@ -378,7 +378,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int drc = wm8994_get_drc(kcontrol->id.name); @@ -462,7 +462,7 @@ static int wm8994_get_retune_mobile_block(const char *name) static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; @@ -485,7 +485,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int block = wm8994_get_retune_mobile_block(kcontrol->id.name); diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index c6cbb3b8ace9..69266332760e 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -412,7 +412,7 @@ static int wm8996_get_retune_mobile_block(const char *name) static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct wm8996_pdata *pdata = &wm8996->pdata; int block = wm8996_get_retune_mobile_block(kcontrol->id.name); @@ -434,7 +434,7 @@ static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int block = wm8996_get_retune_mobile_block(kcontrol->id.name); diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index d18eff31fbbc..185eb97769e7 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -340,7 +340,7 @@ static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6, static int speaker_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); @@ -361,7 +361,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol, static int speaker_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT); unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bb5f7b4e3ebb..d9686dcd024c 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -242,7 +242,7 @@ struct wm_coeff_ctl { static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); @@ -254,7 +254,7 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index b6209662ab13..916817fe6632 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -337,7 +337,7 @@ static void enable_dc_servo(struct snd_soc_codec *codec) static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); int ret; From f6272ff8a5f42c614f4a338013f5323979121e0f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:05 +0100 Subject: [PATCH 0119/1034] ASoC: Add snd_soc_kcontrol_platform() helper function For platform controls snd_kcontrol_chip() currently returns a pointer to the platform that registered the control. With the upcoming consolidation of platform and CODEC controls this will change. Prepare for this by introducing the snd_soc_kcontrol_platform() helper function that will hide the implementation details of how the platform for a control can be obtained. This will allow us to change this easily in the future. The patch also updates all platforms to use this new helper function. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 14 ++++++++++++++ sound/soc/intel/sst-haswell-pcm.c | 8 ++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index e150030b754d..14e7457e2347 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1242,6 +1242,20 @@ static inline struct snd_soc_codec *snd_soc_kcontrol_codec( return snd_kcontrol_chip(kcontrol); } +/** + * snd_soc_kcontrol_platform() - Returns the platform that registerd the control + * @kcontrol: The control for which to get the platform + * + * Note: This function will only work correctly if the control has been + * registered with snd_soc_add_platform_controls() or via table based setup of + * a snd_soc_platform_driver. Otherwise the behavior is undefined. + */ +static inline struct snd_soc_codec *snd_soc_kcontrol_platform( + struct snd_kcontrol *kcontrol) +{ + return snd_kcontrol_chip(kcontrol); +} + int snd_soc_util_init(void); void snd_soc_util_exit(void); diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 0a32dd13a23d..67a5eb3c6196 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -136,7 +136,7 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value) static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct hsw_priv_data *pdata = @@ -174,7 +174,7 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct hsw_priv_data *pdata = @@ -206,7 +206,7 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, static int hsw_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; u32 volume; @@ -231,7 +231,7 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol, static int hsw_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; unsigned int volume = 0; From 6137a5ca326dac848b35bcbdc44b2ff890273375 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:06 +0100 Subject: [PATCH 0120/1034] ASoC: Prepare SOC_SINGLE_XR_SX controls for regmap SOC_SINGLE_XR_SX controls currently only work with CODECs that set the 'reg_word_size' field in their snd_soc_codec_driver struct. Going forward support for ASoC level IO will eventually be removed and all drivers will be converted to regmap. Preparing for the transition this patch adds support for CODECs using regmap for IO to the SOC_SINGLE_XR_SX control. We already have the val_bytes field in the CODEC struct which holds the number of bytes per word, but it is only initialized when regmap is used. Also initialize it for drivers still using legacy IO and update the SOC_SINGLE_XR_SX handlers to use it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..935c59418b19 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3343,7 +3343,7 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; - unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; + unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE; unsigned int regwmask = (1<invert; unsigned long mask = (1UL<nbits)-1; @@ -3389,7 +3389,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; - unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; + unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE; unsigned int regwmask = (1<invert; unsigned long mask = (1UL<nbits)-1; @@ -4292,6 +4292,7 @@ int snd_soc_register_codec(struct device *dev, codec->dev = dev; codec->driver = codec_drv; codec->num_dai = num_dai; + codec->val_bytes = codec_drv->reg_word_size; mutex_init(&codec->mutex); for (i = 0; i < num_dai; i++) { From 96241c83293de346037b9a85e321f52ace210926 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:07 +0100 Subject: [PATCH 0121/1034] ASoC: Move IO functions to soc-io.c soc-core.c is getting quite crowded. Move all IO related functions that are still in soc-core.c to soc-io.c Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 144 ------------------------------------------- sound/soc/soc-io.c | 144 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 144 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 935c59418b19..5c0ed3931285 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2033,38 +2033,6 @@ int snd_soc_codec_writable_register(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); -int snd_soc_platform_read(struct snd_soc_platform *platform, - unsigned int reg) -{ - unsigned int ret; - - if (!platform->driver->read) { - dev_err(platform->dev, "ASoC: platform has no read back\n"); - return -1; - } - - ret = platform->driver->read(platform, reg); - dev_dbg(platform->dev, "read %x => %x\n", reg, ret); - trace_snd_soc_preg_read(platform, reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_platform_read); - -int snd_soc_platform_write(struct snd_soc_platform *platform, - unsigned int reg, unsigned int val) -{ - if (!platform->driver->write) { - dev_err(platform->dev, "ASoC: platform has no write back\n"); - return -1; - } - - dev_dbg(platform->dev, "write %x = %x\n", reg, val); - trace_snd_soc_preg_write(platform, reg, val); - return platform->driver->write(platform, reg, val); -} -EXPORT_SYMBOL_GPL(snd_soc_platform_write); - /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec @@ -2283,118 +2251,6 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); -unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int ret; - - ret = codec->read(codec, reg); - dev_dbg(codec->dev, "read %x => %x\n", reg, ret); - trace_snd_soc_reg_read(codec, reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_read); - -unsigned int snd_soc_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val) -{ - dev_dbg(codec->dev, "write %x = %x\n", reg, val); - trace_snd_soc_reg_write(codec, reg, val); - return codec->write(codec, reg, val); -} -EXPORT_SYMBOL_GPL(snd_soc_write); - -/** - * snd_soc_update_bits - update codec register bits - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Writes new register value. - * - * Returns 1 for change, 0 for no change, or negative error code. - */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned int mask, unsigned int value) -{ - bool change; - unsigned int old, new; - int ret; - - if (codec->using_regmap) { - ret = regmap_update_bits_check(codec->control_data, reg, - mask, value, &change); - } else { - ret = snd_soc_read(codec, reg); - if (ret < 0) - return ret; - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) - ret = snd_soc_write(codec, reg, new); - } - - if (ret < 0) - return ret; - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_update_bits); - -/** - * snd_soc_update_bits_locked - update codec register bits - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Writes new register value, and takes the codec mutex. - * - * Returns 1 for change else 0. - */ -int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, - unsigned int value) -{ - int change; - - mutex_lock(&codec->mutex); - change = snd_soc_update_bits(codec, reg, mask, value); - mutex_unlock(&codec->mutex); - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); - -/** - * snd_soc_test_bits - test register for change - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Tests a register with a new value and checks if the new value is - * different from the old value. - * - * Returns 1 for change else 0. - */ -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned int mask, unsigned int value) -{ - int change; - unsigned int old, new; - - old = snd_soc_read(codec, reg); - new = (old & ~mask) | value; - change = old != new; - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_test_bits); - /** * snd_soc_cnew - create new control * @_template: control template diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 260efc8466fc..bfd7206c178f 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -19,6 +19,150 @@ #include +unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) +{ + unsigned int ret; + + ret = codec->read(codec, reg); + dev_dbg(codec->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_reg_read(codec, reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_read); + +unsigned int snd_soc_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val) +{ + dev_dbg(codec->dev, "write %x = %x\n", reg, val); + trace_snd_soc_reg_write(codec, reg, val); + return codec->write(codec, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_write); + +/** + * snd_soc_update_bits - update codec register bits + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Writes new register value. + * + * Returns 1 for change, 0 for no change, or negative error code. + */ +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, + unsigned int mask, unsigned int value) +{ + bool change; + unsigned int old, new; + int ret; + + if (codec->using_regmap) { + ret = regmap_update_bits_check(codec->control_data, reg, + mask, value, &change); + } else { + ret = snd_soc_read(codec, reg); + if (ret < 0) + return ret; + + old = ret; + new = (old & ~mask) | (value & mask); + change = old != new; + if (change) + ret = snd_soc_write(codec, reg, new); + } + + if (ret < 0) + return ret; + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_update_bits); + +/** + * snd_soc_update_bits_locked - update codec register bits + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Writes new register value, and takes the codec mutex. + * + * Returns 1 for change else 0. + */ +int snd_soc_update_bits_locked(struct snd_soc_codec *codec, + unsigned short reg, unsigned int mask, + unsigned int value) +{ + int change; + + mutex_lock(&codec->mutex); + change = snd_soc_update_bits(codec, reg, mask, value); + mutex_unlock(&codec->mutex); + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); + +/** + * snd_soc_test_bits - test register for change + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Tests a register with a new value and checks if the new value is + * different from the old value. + * + * Returns 1 for change else 0. + */ +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, + unsigned int mask, unsigned int value) +{ + int change; + unsigned int old, new; + + old = snd_soc_read(codec, reg); + new = (old & ~mask) | value; + change = old != new; + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_test_bits); + +int snd_soc_platform_read(struct snd_soc_platform *platform, + unsigned int reg) +{ + unsigned int ret; + + if (!platform->driver->read) { + dev_err(platform->dev, "ASoC: platform has no read back\n"); + return -1; + } + + ret = platform->driver->read(platform, reg); + dev_dbg(platform->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_preg_read(platform, reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_platform_read); + +int snd_soc_platform_write(struct snd_soc_platform *platform, + unsigned int reg, unsigned int val) +{ + if (!platform->driver->write) { + dev_err(platform->dev, "ASoC: platform has no write back\n"); + return -1; + } + + dev_dbg(platform->dev, "write %x = %x\n", reg, val); + trace_snd_soc_preg_write(platform, reg, val); + return platform->driver->write(platform, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_platform_write); + #ifdef CONFIG_REGMAP static int hw_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) From 20a0ec27ea11af0251ffeb5ee2b96cc5c72cb517 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:09 +0100 Subject: [PATCH 0122/1034] ASoC: Remove IO register modifier callbacks There are no ASoC drivers left that use them and new drivers are supposed to use regmap for this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 14 -------- sound/soc/soc-cache.c | 2 -- sound/soc/soc-core.c | 80 +++++-------------------------------------- 3 files changed, 8 insertions(+), 88 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 14e7457e2347..a355d0f9a6f9 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -393,12 +393,6 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_component(struct device *dev); -int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, - unsigned int reg); -int snd_soc_codec_readable_register(struct snd_soc_codec *codec, - unsigned int reg); -int snd_soc_codec_writable_register(struct snd_soc_codec *codec, - unsigned int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, struct regmap *regmap); int snd_soc_cache_sync(struct snd_soc_codec *codec); @@ -692,9 +686,6 @@ struct snd_soc_codec { struct list_head list; struct list_head card_list; int num_dai; - int (*volatile_register)(struct snd_soc_codec *, unsigned int); - int (*readable_register)(struct snd_soc_codec *, unsigned int); - int (*writable_register)(struct snd_soc_codec *, unsigned int); /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ @@ -756,11 +747,6 @@ struct snd_soc_codec_driver { /* codec IO */ unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - int (*display_register)(struct snd_soc_codec *, char *, - size_t, unsigned int); - int (*volatile_register)(struct snd_soc_codec *, unsigned int); - int (*readable_register)(struct snd_soc_codec *, unsigned int); - int (*writable_register)(struct snd_soc_codec *, unsigned int); unsigned int reg_cache_size; short reg_cache_step; short reg_word_size; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index bfed3e4c45ff..3fa77d5f9b75 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -162,8 +162,6 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) i, codec_drv->reg_word_size) == val) continue; - WARN_ON(!snd_soc_codec_writable_register(codec, i)); - ret = snd_soc_write(codec, i, val); if (ret) return ret; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5c0ed3931285..41bd24348520 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -154,22 +154,15 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf, step = codec->driver->reg_cache_step; for (i = 0; i < codec->driver->reg_cache_size; i += step) { - if (!snd_soc_codec_readable_register(codec, i)) - continue; - if (codec->driver->display_register) { - count += codec->driver->display_register(codec, buf + count, - PAGE_SIZE - count, i); - } else { - /* only support larger than PAGE_SIZE bytes debugfs - * entries for the default case */ - if (p >= pos) { - if (total + len >= count - 1) - break; - format_register_str(codec, i, buf + total, len); - total += len; - } - p += len; + /* only support larger than PAGE_SIZE bytes debugfs + * entries for the default case */ + if (p >= pos) { + if (total + len >= count - 1) + break; + format_register_str(codec, i, buf + total, len); + total += len; } + p += len; } total = min(total, count - 1); @@ -1979,60 +1972,6 @@ static struct platform_driver soc_driver = { .remove = soc_remove, }; -/** - * snd_soc_codec_volatile_register: Report if a register is volatile. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indiciating if a CODEC register is volatile. - */ -int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->volatile_register) - return codec->volatile_register(codec, reg); - else - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); - -/** - * snd_soc_codec_readable_register: Report if a register is readable. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indicating if a CODEC register is readable. - */ -int snd_soc_codec_readable_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->readable_register) - return codec->readable_register(codec, reg); - else - return 1; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register); - -/** - * snd_soc_codec_writable_register: Report if a register is writable. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indicating if a CODEC register is writable. - */ -int snd_soc_codec_writable_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->writable_register) - return codec->writable_register(codec, reg); - else - return 1; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); - /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec @@ -4136,9 +4075,6 @@ int snd_soc_register_codec(struct device *dev, codec->write = codec_drv->write; codec->read = codec_drv->read; - codec->volatile_register = codec_drv->volatile_register; - codec->readable_register = codec_drv->readable_register; - codec->writable_register = codec_drv->writable_register; codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; From 98e639fb8a3ed1bf2bd512626c3cfc2992a57113 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:11 +0100 Subject: [PATCH 0123/1034] ASoC: Track which components have been registered with snd_soc_register_component() snd_soc_unregister_component() takes the parent device of the component as a parameter and then looks up the component based on this. This is a problem if multiple components are registered for the same parent device. Currently drivers do not do this, but some drivers register a CPU DAI component and a platform for the same parent device. This will become a problem once platforms are also made components. To make sure that snd_soc_unregister_component() will not accidentally unregister the platform in such a case only consider components that were registered with snd_soc_register_component(). This is only meant as short term stopgap solution to be able to continue componentisation. Long term we'll need something different. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index a355d0f9a6f9..f8a79c17628e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -662,6 +662,7 @@ struct snd_soc_component { unsigned int active; unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ + unsigned int registered_as_component:1; struct list_head list; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 41bd24348520..3314efb365e3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3879,6 +3879,7 @@ int snd_soc_register_component(struct device *dev, } cmpnt->ignore_pmdown_time = true; + cmpnt->registered_as_component = true; return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL, dai_drv, num_dai, true); @@ -3894,7 +3895,7 @@ void snd_soc_unregister_component(struct device *dev) struct snd_soc_component *cmpnt; list_for_each_entry(cmpnt, &component_list, list) { - if (dev == cmpnt->dev) + if (dev == cmpnt->dev && cmpnt->registered_as_component) goto found; } return; From b37f1d123c69c0d7730704d65b83eaac780c0e3b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:12 +0100 Subject: [PATCH 0124/1034] ASoC: Let snd_soc_platform subclass snd_soc_component There is an increasing amount of code that is very similar between platforms, CODECS and other components. Making platforms a component will allow us to share this code. For now the patch just adds component and component_driver fields to the platform and platform_driver structs and registers the platform as a component. Followup patches will be used to consolidate code between the different types of components. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 16 ++++++++++++++++ sound/soc/soc-core.c | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index f8a79c17628e..94a2dc20ad6e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -778,6 +778,7 @@ struct snd_soc_platform_driver { int (*remove)(struct snd_soc_platform *); int (*suspend)(struct snd_soc_dai *dai); int (*resume)(struct snd_soc_dai *dai); + struct snd_soc_component_driver component_driver; /* pcm creation and destruction */ int (*pcm_new)(struct snd_soc_pcm_runtime *); @@ -831,6 +832,8 @@ struct snd_soc_platform { struct list_head list; struct list_head card_list; + struct snd_soc_component component; + struct snd_soc_dapm_context dapm; #ifdef CONFIG_DEBUG_FS @@ -1107,6 +1110,19 @@ static inline struct snd_soc_codec *snd_soc_component_to_codec( return container_of(component, struct snd_soc_codec, component); } +/** + * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in + * @component: The component to cast to a platform + * + * This function must only be used on components that are known to be platforms. + * Otherwise the behavior is undefined. + */ +static inline struct snd_soc_platform *snd_soc_component_to_platform( + struct snd_soc_component *component) +{ + return container_of(component, struct snd_soc_platform, component); +} + /* codec IO */ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); unsigned int snd_soc_write(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3314efb365e3..a95c7e524dfc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3921,6 +3921,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_component); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv) { + int ret; + /* create platform component name */ platform->name = fmt_single_name(dev, &platform->id); if (platform->name == NULL) @@ -3933,6 +3935,16 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->dapm.stream_event = platform_drv->stream_event; mutex_init(&platform->mutex); + /* register component */ + ret = __snd_soc_register_component(dev, &platform->component, + &platform_drv->component_driver, + NULL, NULL, 0, false); + if (ret < 0) { + dev_err(platform->component.dev, + "ASoC: Failed to register component: %d\n", ret); + return ret; + } + mutex_lock(&client_mutex); list_add(&platform->list, &platform_list); mutex_unlock(&client_mutex); @@ -3974,6 +3986,8 @@ EXPORT_SYMBOL_GPL(snd_soc_register_platform); */ void snd_soc_remove_platform(struct snd_soc_platform *platform) { + snd_soc_unregister_component(platform->dev); + mutex_lock(&client_mutex); list_del(&platform->list); mutex_unlock(&client_mutex); From 261edc7013a7435e40fd5ebb3682eac6fc3c15ea Mon Sep 17 00:00:00 2001 From: Nariman Poushin Date: Mon, 31 Mar 2014 15:47:12 +0100 Subject: [PATCH 0125/1034] ASoC: core: Fail probe if we fail to add dai widgets Signed-off-by: Nariman Poushin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..d5710fc79b49 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1132,8 +1132,15 @@ static int soc_probe_codec(struct snd_soc_card *card, driver->num_dapm_widgets); /* Create DAPM widgets for each DAI stream */ - list_for_each_entry(dai, &codec->component.dai_list, list) - snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); + list_for_each_entry(dai, &codec->component.dai_list, list) { + ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); + + if (ret != 0) { + dev_err(codec->dev, + "Failed to create DAI widgets %d\n", ret); + goto err_probe; + } + } codec->dapm.idle_bias_off = driver->idle_bias_off; From b318ad503698160183fe5e0752b9a1bb3e558026 Mon Sep 17 00:00:00 2001 From: Nariman Poushin Date: Tue, 1 Apr 2014 13:59:33 +0100 Subject: [PATCH 0126/1034] ASoC: core: Fail codec probe if we fail to add controls Signed-off-by: Nariman Poushin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d5710fc79b49..777453158347 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1127,9 +1127,17 @@ static int soc_probe_codec(struct snd_soc_card *card, soc_init_codec_debugfs(codec); - if (driver->dapm_widgets) - snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, - driver->num_dapm_widgets); + if (driver->dapm_widgets) { + ret = snd_soc_dapm_new_controls(&codec->dapm, + driver->dapm_widgets, + driver->num_dapm_widgets); + + if (ret != 0) { + dev_err(codec->dev, + "Failed to create new controls %d\n", ret); + goto err_probe; + } + } /* Create DAPM widgets for each DAI stream */ list_for_each_entry(dai, &codec->component.dai_list, list) { From 1a39019e939f620f39a1b914231ab6ba9013b208 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 8 Apr 2014 11:18:10 +0800 Subject: [PATCH 0127/1034] ASoC: core: Allow snd_soc_update_bits use 32 bits register Change reg's type from unsigned short to unsigned int. So that we can use 32 bits reg value in snd_soc_update_bits. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- include/sound/soc.h | 6 +++--- sound/soc/soc-core.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..4ed706bf11d1 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -469,12 +469,12 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, #endif /* codec register bit access */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, + unsigned int reg, unsigned int mask, unsigned int value); -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 777453158347..7f0a9297e420 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2330,7 +2330,7 @@ EXPORT_SYMBOL_GPL(snd_soc_write); * * Returns 1 for change, 0 for no change, or negative error code. */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value) { bool change; @@ -2371,7 +2371,7 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits); * Returns 1 for change else 0. */ int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, + unsigned int reg, unsigned int mask, unsigned int value) { int change; @@ -2396,7 +2396,7 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); * * Returns 1 for change else 0. */ -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value) { int change; @@ -2911,7 +2911,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, int min = mc->min; int mask = (1 << (fls(min + max) - 1)) - 1; int err = 0; - unsigned short val, val_mask, val2 = 0; + unsigned int val, val_mask, val2 = 0; val_mask = mask << shift; val = (ucontrol->value.integer.value[0] + min) & mask; From 1a95d8d09ef7e40563afd587cce52868e3d076a0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 18 Mar 2014 15:20:37 +0200 Subject: [PATCH 0128/1034] ASoC: davinci-pcm: Add empty functions for !CONFIG_SND_DAVINCI_SOC builds To save drivers using davinci-pcm and edma-pcm the need to fiddle with !CONFIG_SND_DAVINCI_SOC in their code. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-pcm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fbb710c76c08..5fd4737ab398 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -29,7 +29,17 @@ struct davinci_pcm_dma_params { unsigned int fifo_level; }; +#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC) int davinci_soc_platform_register(struct device *dev); void davinci_soc_platform_unregister(struct device *dev); +#else +static inline int davinci_soc_platform_register(struct device *dev) +{ + return 0; +} +static inline void davinci_soc_platform_unregister(struct device *dev) +{ +} +#endif /* CONFIG_SND_DAVINCI_SOC */ #endif From d5902f693698076e5bda44cbfa999e9c02bb83ab Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:07 +0300 Subject: [PATCH 0129/1034] ASoC: davinci-mcasp: Assign the dma_data earlier in dai_probe callback Set up the playback_dma_data/capture_dma_data for the dai at probe time since the generic dmaengine PCM stack needs to have access to this information early. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 36 ++++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 4f75cac462d1..b4c5cf58b030 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -716,22 +716,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, return ret; } -static int davinci_mcasp_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); - - if (mcasp->version == MCASP_VERSION_4) - snd_soc_dai_set_dma_data(dai, substream, - &mcasp->dma_data[substream->stream]); - else - snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); - - return 0; -} - static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { - .startup = davinci_mcasp_startup, .trigger = davinci_mcasp_trigger, .hw_params = davinci_mcasp_hw_params, .set_fmt = davinci_mcasp_set_dai_fmt, @@ -739,6 +724,25 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .set_sysclk = davinci_mcasp_set_sysclk, }; +static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) +{ + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + if (mcasp->version == MCASP_VERSION_4) { + /* Using dmaengine PCM */ + dai->playback_dma_data = + &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + dai->capture_dma_data = + &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; + } else { + /* Using davinci-pcm */ + dai->playback_dma_data = mcasp->dma_params; + dai->capture_dma_data = mcasp->dma_params; + } + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int davinci_mcasp_suspend(struct snd_soc_dai *dai) { @@ -792,6 +796,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) static struct snd_soc_dai_driver davinci_mcasp_dai[] = { { .name = "davinci-mcasp.0", + .probe = davinci_mcasp_dai_probe, .suspend = davinci_mcasp_suspend, .resume = davinci_mcasp_resume, .playback = { @@ -811,6 +816,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }, { .name = "davinci-mcasp.1", + .probe = davinci_mcasp_dai_probe, .playback = { .channels_min = 1, .channels_max = 384, From f5b02b4a2cb7eaa223ddaba8e4338b31bcdaf369 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:08 +0300 Subject: [PATCH 0130/1034] ASoC: davinci-mcasp: Fix debug typo in davinci_mcasp_hw_params() requred -> required Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b4c5cf58b030..eb46dc69248f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -620,7 +620,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, if (mcasp->bclk_master) { unsigned int bclk_freq = snd_soc_params_to_bclk(params); if (mcasp->sysclk_freq % bclk_freq != 0) { - dev_err(mcasp->dev, "Can't produce requred BCLK\n"); + dev_err(mcasp->dev, "Can't produce required BCLK\n"); return -EINVAL; } davinci_mcasp_set_clkdiv( From 0bf0e8aeceaf4b12524559fce9c6b91a90b63381 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:09 +0300 Subject: [PATCH 0131/1034] ASoC: davinci-mcasp: Simplify and clean up the AFIFO configuration code We can have more linear code flow by using variables in mcasp_common_hw_param() related to the AFIFO configuration. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 48 +++++++++++++++---------------- sound/soc/davinci/davinci-mcasp.h | 1 + 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index eb46dc69248f..aa063a4e7b0c 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -37,6 +37,8 @@ #include "davinci-pcm.h" #include "davinci-mcasp.h" +#define MCASP_MAX_AFIFO_DEPTH 64 + struct davinci_mcasp_context { u32 txfmtctl; u32 rxfmtctl; @@ -469,9 +471,9 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int i; u8 tx_ser = 0; u8 rx_ser = 0; - u8 ser; u8 slots = mcasp->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; + u8 active_serializers, numevt; u32 reg; /* Default configuration */ if (mcasp->version != MCASP_VERSION_4) @@ -505,36 +507,34 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, } } - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - ser = tx_ser; - else - ser = rx_ser; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + active_serializers = tx_ser; + numevt = mcasp->txnumevt; + reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + } else { + active_serializers = rx_ser; + numevt = mcasp->rxnumevt; + reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + } - if (ser < max_active_serializers) { + if (active_serializers < max_active_serializers) { dev_warn(mcasp->dev, "stream has more channels (%d) than are " - "enabled in mcasp (%d)\n", channels, ser * slots); + "enabled in mcasp (%d)\n", channels, + active_serializers * slots); return -EINVAL; } - if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (mcasp->txnumevt * tx_ser > 64) - mcasp->txnumevt = 1; + /* AFIFO is not in use */ + if (!numevt) + return 0; - reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; - mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK); - mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8), - NUMEVT_MASK); - } + if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) + numevt = active_serializers; - if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { - if (mcasp->rxnumevt * rx_ser > 64) - mcasp->rxnumevt = 1; - - reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; - mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK); - mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8), - NUMEVT_MASK); - } + /* Configure the AFIFO */ + numevt *= active_serializers; + mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); + mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); return 0; } diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 8fed757d6087..98fbc451892a 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -283,6 +283,7 @@ */ #define FIFO_ENABLE BIT(16) #define NUMEVT_MASK (0xFF << 8) +#define NUMEVT(x) (((x) & 0xFF) << 8) #define NUMDMA_MASK (0xFF) #endif /* DAVINCI_MCASP_H */ From 5f04c603a52d4951e6f6b2f059049e7c5ee93db7 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:10 +0300 Subject: [PATCH 0132/1034] ASoC: davinci-mcasp: Configure the AFIFO and DMA burst size at the same place Move the dma_params->fifo_level and dma_data->maxburst configuration to the mcasp_common_hw_param() function where we configure the AFIFO registers. It makes the code regarding to AFIFO and DMA configuration more easy to follow since it is now clear how the AFIFO and how the DMA is going to be configured. Previously this has been done in two functions using a bit different calculation form - which ended up with the same result in both case at the end, but it was confusing. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index aa063a4e7b0c..ab4fa1291795 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -468,6 +468,8 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int channels) { + struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; + struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; int i; u8 tx_ser = 0; u8 rx_ser = 0; @@ -524,9 +526,14 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return -EINVAL; } + /* AFIFO is not in use */ - if (!numevt) + if (!numevt) { + /* Configure the burst size for platform drivers */ + dma_params->fifo_level = 0; + dma_data->maxburst = 0; return 0; + } if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) numevt = active_serializers; @@ -536,6 +543,10 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); + /* Configure the burst size for platform drivers */ + dma_params->fifo_level = numevt; + dma_data->maxburst = numevt; + return 0; } @@ -607,12 +618,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[substream->stream]; - struct snd_dmaengine_dai_dma_data *dma_data = - &mcasp->dma_data[substream->stream]; int word_length; - u8 fifo_level; - u8 slots = mcasp->tdm_slots; - u8 active_serializers; int channels = params_channels(params); int ret; @@ -671,21 +677,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* Calculate FIFO level */ - active_serializers = (channels + slots - 1) / slots; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - fifo_level = mcasp->txnumevt * active_serializers; - else - fifo_level = mcasp->rxnumevt * active_serializers; - - if (mcasp->version == MCASP_VERSION_2 && !fifo_level) + if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level) dma_params->acnt = 4; else dma_params->acnt = dma_params->data_type; - dma_params->fifo_level = fifo_level; - dma_data->maxburst = fifo_level; - davinci_config_channel_size(mcasp, word_length); return 0; From dd093a0f1962fb71e8852411f03fec7290027a90 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:11 +0300 Subject: [PATCH 0133/1034] ASoC: davinic-mcasp: Adopt the AFIFO/DMA configuration to the stream (dynamic depth) Configure the AFIFO numevt parameter based on the requested tx/rx_numevt, active serializers and period size in words. In this way McASP can adopt it's (and the DMA) configuration runtime and can pick the most optimal setup which satisfy the parameters. This way we do not need to place any constraint on the stream itself, allowing application greater freedom on how they want to set up ALSA. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index ab4fa1291795..9454d123f4bb 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -466,7 +466,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, } static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, - int channels) + int period_words, int channels) { struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; @@ -475,7 +475,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, u8 rx_ser = 0; u8 slots = mcasp->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; - u8 active_serializers, numevt; + int active_serializers, numevt, n; u32 reg; /* Default configuration */ if (mcasp->version != MCASP_VERSION_4) @@ -526,7 +526,6 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return -EINVAL; } - /* AFIFO is not in use */ if (!numevt) { /* Configure the burst size for platform drivers */ @@ -535,11 +534,26 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return 0; } - if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) + if (period_words % active_serializers) { + dev_err(mcasp->dev, "Invalid combination of period words and " + "active serializers: %d, %d\n", period_words, + active_serializers); + return -EINVAL; + } + + /* + * Calculate the optimal AFIFO depth for platform side: + * The number of words for numevt need to be in steps of active + * serializers. + */ + n = numevt % active_serializers; + if (n) + numevt += (active_serializers - n); + while (period_words % numevt && numevt > 0) + numevt -= active_serializers; + if (numevt <= 0) numevt = active_serializers; - /* Configure the AFIFO */ - numevt *= active_serializers; mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); @@ -620,6 +634,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, &mcasp->dma_params[substream->stream]; int word_length; int channels = params_channels(params); + int period_size = params_period_size(params); int ret; /* If mcasp is BCLK master we need to set BCLK divider */ @@ -633,7 +648,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); } - ret = mcasp_common_hw_param(mcasp, substream->stream, channels); + ret = mcasp_common_hw_param(mcasp, substream->stream, + period_size * channels, channels); if (ret) return ret; From 33445643c3146fa43af3e9aa1cce08da9fe03157 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:12 +0300 Subject: [PATCH 0134/1034] ASoC: davinci-mcasp: Fine tune and correct the DMA burst configuration When the AFIFO is not enabled but more than one serializers are used the DMA need to transfer number of words equal to active serializers when a DMA request is generated. When configuring the burst for the DMA avoid using value '1' for the burst since it is going to enable additional logic in the DMA drivers. Burst '1' means that the DMA should send/receive one word per DMA requests. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9454d123f4bb..196158f2d1c4 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -529,8 +529,19 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, /* AFIFO is not in use */ if (!numevt) { /* Configure the burst size for platform drivers */ - dma_params->fifo_level = 0; - dma_data->maxburst = 0; + if (active_serializers > 1) { + /* + * If more than one serializers are in use we have one + * DMA request to provide data for all serializers. + * For example if three serializers are enabled the DMA + * need to transfer three words per DMA request. + */ + dma_params->fifo_level = active_serializers; + dma_data->maxburst = active_serializers; + } else { + dma_params->fifo_level = 0; + dma_data->maxburst = 0; + } return 0; } @@ -558,6 +569,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); /* Configure the burst size for platform drivers */ + if (numevt == 1) + numevt = 0; dma_params->fifo_level = numevt; dma_data->maxburst = numevt; From 6dfa9a4e6aacba70bff24c47871ac9aba3e76020 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:42 +0300 Subject: [PATCH 0135/1034] ASoC: davinci-mcasp: Format data delay configuration enhancement Use intermediate variable for the data delay needed for the specific format and write the register after the format configuration at once. This will help to control the number of lines as support for more formats going to be added. Also fixes a case when we switch between two formats with different delay requirements. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 196158f2d1c4..f0c98653bfe7 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -271,6 +271,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); int ret = 0; + u32 data_delay; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -278,18 +279,25 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + + /* No delay after FS */ + data_delay = 0; break; default: /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* make 1st data bit occur one ACLK cycle after the frame sync */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); + /* 1st data bit occur one ACLK cycle after the frame sync */ + data_delay = 1; break; } + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay), + FSXDLY(3)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay), + FSRDLY(3)); + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* codec is clock and frame slave */ From 188edc59c297fcd971d6a4ae5f5f5dacff7b315b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:43 +0300 Subject: [PATCH 0136/1034] ASoC: davinci-mcasp: Support for DSP_A format DSP_A is like DSP_B mode but with one bit delay after the FS. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index f0c98653bfe7..58b6d47cc8f8 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -275,6 +275,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + + /* 1st data bit occur one ACLK cycle after the frame sync */ + data_delay = 1; + break; case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); From 83f12503bd1fb18d3fd460871660b34faf671918 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:44 +0300 Subject: [PATCH 0137/1034] ASoC: davinci-mcasp: Move the FS polarity change out from the switch case FS polarity can be either rising or falling edge in McASP. Instead of accessing the registers in every switch/case set a flag and write the registers after the switch for the invert configuration. This change will help when adding support for more formats also. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 58b6d47cc8f8..113e74c9479f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -272,6 +272,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); int ret = 0; u32 data_delay; + bool fs_pol_rising; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -351,39 +352,39 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_NF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = true; break; case SND_SOC_DAIFMT_NB_IF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = false; break; case SND_SOC_DAIFMT_IB_IF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = false; break; case SND_SOC_DAIFMT_NB_NF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = true; break; default: ret = -EINVAL; - break; + goto out; + } + + if (fs_pol_rising) { + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + } else { + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); } out: pm_runtime_put_sync(mcasp->dev); From ffd950f75dd71f13194b5d5c8ec67926a1996102 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:45 +0300 Subject: [PATCH 0138/1034] ASoC: davinci-mcasp: Add support for I2S format The FS needs to be inverted in McASP compared to other supported formats. Use a flag to indicate if the FS needs to be inverted. At the same time fail when non supported format is asked since the default case was anyways configuring McASP to a not valid format. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 113e74c9479f..d4d640004bed 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -273,6 +273,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, int ret = 0; u32 data_delay; bool fs_pol_rising; + bool inv_fs = false; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -291,14 +292,19 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* No delay after FS */ data_delay = 0; break; - default: + case SND_SOC_DAIFMT_I2S: /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; + /* FS need to be inverted */ + inv_fs = true; break; + default: + ret = -EINVAL; + goto out; } mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay), @@ -379,6 +385,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, goto out; } + if (inv_fs) + fs_pol_rising = !fs_pol_rising; + if (fs_pol_rising) { mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); From 423761e0cab39c98f0fd9387ea44b98c2a4ca6fa Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:46 +0300 Subject: [PATCH 0139/1034] ASoC: davinci-mcasp: Support for LEFT_J format Configuration for LEFT_J format. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index d4d640004bed..2b6722024fbd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -302,6 +302,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* FS need to be inverted */ inv_fs = true; break; + case SND_SOC_DAIFMT_LEFT_J: + /* configure a full-word SYNC pulse (LRCLK) */ + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + /* No delay after FS */ + data_delay = 0; + break; default: ret = -EINVAL; goto out; From 3c25f916d378da6f06874abfc5c18e5a40e2d8c0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:47 +0300 Subject: [PATCH 0140/1034] ASoC: davinci-mcasp: Remove excess empty lines from davinci_mcasp_set_dai_fmt() To make the code look uniform. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 2b6722024fbd..8007fcf428d9 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -280,7 +280,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_DSP_A: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; break; @@ -288,7 +287,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* No delay after FS */ data_delay = 0; break; @@ -296,7 +294,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; /* FS need to be inverted */ @@ -356,7 +353,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); mcasp->bclk_master = 0; break; - default: ret = -EINVAL; goto out; @@ -368,25 +364,21 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = true; break; - case SND_SOC_DAIFMT_NB_IF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = false; break; - case SND_SOC_DAIFMT_IB_IF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = false; break; - case SND_SOC_DAIFMT_NB_NF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = true; break; - default: ret = -EINVAL; goto out; From eba9e06f0ceb2ea3342e72577b244d8b02645396 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 16 Mar 2014 08:21:34 +0400 Subject: [PATCH 0141/1034] ASoC: fsl: Separation of the main audio options and boards This patch provide separation of the main audio options and boards. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 338a91642471..0b4315d5af77 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,3 +1,5 @@ +menu "SoC Audio for Freescale CPUs" + config SND_SOC_FSL_SAI tristate select REGMAP_MMIO @@ -18,13 +20,27 @@ config SND_SOC_FSL_ESAI config SND_SOC_FSL_UTILS tristate -menuconfig SND_POWERPC_SOC +config SND_SOC_IMX_PCM_DMA + tristate + select SND_SOC_GENERIC_DMAENGINE_PCM + +config SND_SOC_IMX_AUDMUX + tristate + +config SND_POWERPC_SOC tristate "SoC Audio for Freescale PowerPC CPUs" depends on FSL_SOC || PPC_MPC52xx help Say Y or M if you want to add support for codecs attached to the PowerPC CPUs. +config SND_IMX_SOC + tristate "SoC Audio for Freescale i.MX CPUs" + depends on ARCH_MXC || COMPILE_TEST + help + Say Y or M if you want to add support for codecs attached to + the i.MX CPUs. + if SND_POWERPC_SOC config SND_MPC52xx_DMA @@ -33,6 +49,8 @@ config SND_MPC52xx_DMA config SND_SOC_POWERPC_DMA tristate +comment "SoC Audio support for Freescale PPC boards:" + config SND_SOC_MPC8610_HPCD tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" # I2C is necessary for the CS4270 driver @@ -110,13 +128,6 @@ config SND_MPC52xx_SOC_EFIKA endif # SND_POWERPC_SOC -menuconfig SND_IMX_SOC - tristate "SoC Audio for Freescale i.MX CPUs" - depends on ARCH_MXC || COMPILE_TEST - help - Say Y or M if you want to add support for codecs attached to - the i.MX CPUs. - if SND_IMX_SOC config SND_SOC_IMX_SSI @@ -127,12 +138,7 @@ config SND_SOC_IMX_PCM_FIQ tristate select FIQ -config SND_SOC_IMX_PCM_DMA - tristate - select SND_SOC_GENERIC_DMAENGINE_PCM - -config SND_SOC_IMX_AUDMUX - tristate +comment "SoC Audio support for Freescale i.MX boards:" config SND_MXC_SOC_WM1133_EV1 tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" @@ -225,3 +231,5 @@ config SND_SOC_IMX_MC13783 select SND_SOC_IMX_PCM_DMA endif # SND_IMX_SOC + +endmenu From 204dec93eaaba3a7afdc09aa3c3f6d08c773a367 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 16 Mar 2014 08:21:35 +0400 Subject: [PATCH 0142/1034] ASoC: fsl: Allow to select individual common options This patch allow to select individual common sound options and as a result allow using sound cards/codecs based on DT description. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 0b4315d5af77..7a7eaf32158f 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,16 +1,28 @@ menu "SoC Audio for Freescale CPUs" +comment "Common SoC Audio options for Freescale CPUs:" + config SND_SOC_FSL_SAI tristate select REGMAP_MMIO select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_FSL_SSI - tristate + tristate "Synchronous Serial Interface module support" + help + Say Y if you want to add Synchronous Serial Interface (SSI) + support for the Freescale CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_SOC_FSL_SPDIF - tristate + tristate "Sony/Philips Digital Interface module support" select REGMAP_MMIO + help + Say Y if you want to add Sony/Philips Digital Interface (SPDIF) + support for the Freescale CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_SOC_FSL_ESAI tristate @@ -25,7 +37,12 @@ config SND_SOC_IMX_PCM_DMA select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_IMX_AUDMUX - tristate + tristate "Digital Audio Mux module support" + help + Say Y if you want to add Digital Audio Mux (AUDMUX) support + for the ARM i.MX CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_POWERPC_SOC tristate "SoC Audio for Freescale PowerPC CPUs" From 413312aa17ceefe7003ad690778ab72f023128f0 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 28 Mar 2014 19:39:25 +0800 Subject: [PATCH 0143/1034] ASoC: fsl_sai: Improve fsl_sai_isr() This patch improves fsl_sai_isr() in these ways: 1, Add comment for mask fetching code. 2, Return IRQ_NONE if the IRQ is not for the device. 3, Use regmap_write() instead of regmap_update_bits(). Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 64 +++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 56da8c8c5960..7194d9280020 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -30,62 +30,88 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) { struct fsl_sai *sai = (struct fsl_sai *)devid; struct device *dev = &sai->pdev->dev; - u32 xcsr, mask; + u32 flags, xcsr, mask; + bool irq_none = true; - /* Only handle those what we enabled */ + /* + * Both IRQ status bits and IRQ mask bits are in the xCSR but + * different shifts. And we here create a mask only for those + * IRQs that we activated. + */ mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; /* Tx IRQ */ regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); - xcsr &= mask; + flags = xcsr & mask; - if (xcsr & FSL_SAI_CSR_WSF) + if (flags) + irq_none = false; + else + goto irq_rx; + + if (flags & FSL_SAI_CSR_WSF) dev_dbg(dev, "isr: Start of Tx word detected\n"); - if (xcsr & FSL_SAI_CSR_SEF) + if (flags & FSL_SAI_CSR_SEF) dev_warn(dev, "isr: Tx Frame sync error detected\n"); - if (xcsr & FSL_SAI_CSR_FEF) { + if (flags & FSL_SAI_CSR_FEF) { dev_warn(dev, "isr: Transmit underrun detected\n"); /* FIFO reset for safety */ xcsr |= FSL_SAI_CSR_FR; } - if (xcsr & FSL_SAI_CSR_FWF) + if (flags & FSL_SAI_CSR_FWF) dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); - if (xcsr & FSL_SAI_CSR_FRF) + if (flags & FSL_SAI_CSR_FRF) dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); + flags &= FSL_SAI_CSR_xF_W_MASK; + xcsr &= ~FSL_SAI_CSR_xF_MASK; + if (flags) + regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); + +irq_rx: /* Rx IRQ */ regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); - xcsr &= mask; + flags = xcsr & mask; - if (xcsr & FSL_SAI_CSR_WSF) + if (flags) + irq_none = false; + else + goto out; + + if (flags & FSL_SAI_CSR_WSF) dev_dbg(dev, "isr: Start of Rx word detected\n"); - if (xcsr & FSL_SAI_CSR_SEF) + if (flags & FSL_SAI_CSR_SEF) dev_warn(dev, "isr: Rx Frame sync error detected\n"); - if (xcsr & FSL_SAI_CSR_FEF) { + if (flags & FSL_SAI_CSR_FEF) { dev_warn(dev, "isr: Receive overflow detected\n"); /* FIFO reset for safety */ xcsr |= FSL_SAI_CSR_FR; } - if (xcsr & FSL_SAI_CSR_FWF) + if (flags & FSL_SAI_CSR_FWF) dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); - if (xcsr & FSL_SAI_CSR_FRF) + if (flags & FSL_SAI_CSR_FRF) dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); + flags &= FSL_SAI_CSR_xF_W_MASK; + xcsr &= ~FSL_SAI_CSR_xF_MASK; - return IRQ_HANDLED; + if (flags) + regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); + +out: + if (irq_none) + return IRQ_NONE; + else + return IRQ_HANDLED; } static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, From e6b398465821fb8e08d208bd4ef2b5b73ce87b58 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 11:17:06 +0800 Subject: [PATCH 0144/1034] ASoC: fsl_sai: Fix buggy configurations in trigger() The current trigger() has two crucial problems: 1) The DMA request enabling operations (FSL_SAI_CSR_FRDE) for Tx and Rx are now totally exclusive: It would fail to run simultaneous Tx-Rx cases. 2) The TERE disabling operation depends on an incorrect condition -- active reference count that only gets increased in snd_pcm_open() and decreased in snd_pcm_close(): The TERE would never get cleared. So this patch overwrites the trigger function by following these rules: A) We continue to support tx-async-while-rx-sync-to-tx case alone, which's originally limited by this fsl_sai driver, but we make the code easy to modify for the further support of the opposite case. B) We enable both TE and RE for PLAYBACK stream or CAPTURE stream but only enabling the DMA request bit (FSL_SAI_CSR_FRDE) of the current direction due to the requirement of SAI -- For tx-async-while-rx-sync-to-tx case, the receiver is enabled only when both the transmitter and receiver are enabled. Tested cases: a) aplay test.wav -d5 b) arecord -r44100 -c2 -fS16_LE test.wav -d5 c) arecord -r44100 -c2 -fS16_LE -d5 | aplay d) (aplay test2.wav &); sleep 1; arecord -r44100 -c2 -fS16_LE test.wav -d1 e) (arecord -r44100 -c2 -fS16_LE test.wav -d5 &); sleep 1; aplay test.wav -d1 Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 35 +++++++++++++++++------------------ sound/soc/fsl/fsl_sai.h | 10 ++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 7194d9280020..80cca7bb2a11 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -365,6 +365,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 tcsr, rcsr; /* @@ -379,14 +380,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tcsr |= FSL_SAI_CSR_FRDE; - rcsr &= ~FSL_SAI_CSR_FRDE; - } else { - rcsr |= FSL_SAI_CSR_FRDE; - tcsr &= ~FSL_SAI_CSR_FRDE; - } - /* * It is recommended that the transmitter is the last enabled * and the first disabled. @@ -395,22 +388,28 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - tcsr |= FSL_SAI_CSR_TERE; - rcsr |= FSL_SAI_CSR_TERE; + if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, + FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, + FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); + } - regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); - regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (!(cpu_dai->playback_active || cpu_dai->capture_active)) { - tcsr &= ~FSL_SAI_CSR_TERE; - rcsr &= ~FSL_SAI_CSR_TERE; - } + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_FRDE, 0); - regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); - regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); + if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, + FSL_SAI_CSR_TERE, 0); + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, + FSL_SAI_CSR_TERE, 0); + } break; default: return -EINVAL; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index a264185c7138..64b6fe72cd08 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -35,6 +35,16 @@ #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ +#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) +#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) +#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) +#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) +#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) +#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) +#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) +#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) +#define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) + /* SAI Transmit/Recieve Control Register */ #define FSL_SAI_CSR_TERE BIT(31) #define FSL_SAI_CSR_FR BIT(25) From 8abba5d64835c636d97ac0009ab7430ed832cb93 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 11:17:07 +0800 Subject: [PATCH 0145/1034] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams We only enable one side interrupt for each stream since over/underrun on the opposite stream would be resulted from what we previously did, enabling TERE but remaining FRDE disabled, even though the xrun on the opposite direction will not break the current stream. Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 8 ++++++-- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 80cca7bb2a11..21de5bd1c9c5 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -395,6 +395,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); } + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); break; @@ -403,6 +405,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_PUSH: regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_FRDE, 0); + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_xIE_MASK, 0); if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { regmap_update_bits(sai->regmap, FSL_SAI_TCSR, @@ -463,8 +467,8 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS); - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS); + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_TX * 2); regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 64b6fe72cd08..be26d46ee737 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -58,6 +58,7 @@ #define FSL_SAI_CSR_FWF BIT(17) #define FSL_SAI_CSR_FRF BIT(16) #define FSL_SAI_CSR_xIE_SHIFT 8 +#define FSL_SAI_CSR_xIE_MASK (0x1f << FSL_SAI_CSR_xIE_SHIFT) #define FSL_SAI_CSR_WSIE BIT(12) #define FSL_SAI_CSR_SEIE BIT(11) #define FSL_SAI_CSR_FEIE BIT(10) From c754064453e0d48043bd6a111f5c1f8ef1b75f7e Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 19:34:09 +0800 Subject: [PATCH 0146/1034] ASoC: fsl_sai: Add imx6sx platform support The next coming i.MX6 Solo X SoC also contains SAI module while we use imp_pcm_init() for i.MX platform. So this patch adds one compatible route for imx6sx and updates the DT doc accordingly. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-sai.txt | 2 +- sound/soc/fsl/fsl_sai.c | 12 ++++++++++-- sound/soc/fsl/fsl_sai.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 98611a6761c0..35c09fe5847a 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -7,7 +7,7 @@ codec/DSP interfaces. Required properties: -- compatible: Compatible list, contains "fsl,vf610-sai". +- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". - reg: Offset and length of the register set for the device. - clocks: Must contain an entry for each entry in clock-names. - clock-names : Must include the "sai" entry. diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 21de5bd1c9c5..dde084273c64 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -22,6 +22,7 @@ #include #include "fsl_sai.h" +#include "imx-pcm.h" #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ FSL_SAI_CSR_FEIE) @@ -592,6 +593,9 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->pdev = pdev; + if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai")) + sai->sai_on_imx = true; + sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); if (sai->big_endian_regs) fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; @@ -634,12 +638,16 @@ static int fsl_sai_probe(struct platform_device *pdev) if (ret) return ret; - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); + if (sai->sai_on_imx) + return imx_pcm_dma_init(pdev); + else + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); } static const struct of_device_id fsl_sai_ids[] = { { .compatible = "fsl,vf610-sai", }, + { .compatible = "fsl,imx6sx-sai", }, { /* sentinel */ } }; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index be26d46ee737..677670d62fcd 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -130,6 +130,7 @@ struct fsl_sai { bool big_endian_regs; bool big_endian_data; bool is_dsp_mode; + bool sai_on_imx; struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; From ca3e35c7a37cb59b12a1839d03c621cf8fa9a3d9 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Thu, 10 Apr 2014 23:26:15 +0800 Subject: [PATCH 0147/1034] ASoC: fsl_sai: Add clock controls for SAI The SAI mainly has the following clocks: bus clock control and configure registers and to generate synchronous interrupts and DMA requests. mclk1, mclk2, mclk3 to generate the bit clock when the receiver or transmitter is configured for an internally generated bit clock. So this patch adds these clocks and their clock controls to the driver. [ To concern the old DTB cases, I've added a bit of extra code to make the driver compatible with them. And by marking clock NULL if failed to get, the clk_prepare() or clk_get_rate() would easily return 0 so no further path should be broken. -- by Nicolin ] Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl-sai.txt | 9 +++-- sound/soc/fsl/fsl_sai.c | 38 ++++++++++++++++++- sound/soc/fsl/fsl_sai.h | 4 ++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 35c09fe5847a..0f4e23828190 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -10,7 +10,8 @@ Required properties: - compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". - reg: Offset and length of the register set for the device. - clocks: Must contain an entry for each entry in clock-names. -- clock-names : Must include the "sai" entry. +- clock-names : Must include the "bus" for register access and "mclk1" "mclk2" + "mclk3" for bit clock and frame clock providing. - dmas : Generic dma devicetree binding as described in Documentation/devicetree/bindings/dma/dma.txt. - dma-names : Two dmas have to be defined, "tx" and "rx". @@ -30,8 +31,10 @@ sai2: sai@40031000 { reg = <0x40031000 0x1000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2_1>; - clocks = <&clks VF610_CLK_SAI2>; - clock-names = "sai"; + clocks = <&clks VF610_CLK_PLATFORM_BUS>, + <&clks VF610_CLK_SAI2>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; dma-names = "tx", "rx"; dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index dde084273c64..1c93282fbd26 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -427,7 +427,15 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + struct device *dev = &sai->pdev->dev; u32 reg; + int ret; + + ret = clk_prepare_enable(sai->bus_clk); + if (ret) { + dev_err(dev, "failed to enable bus clock: %d\n", ret); + return ret; + } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = FSL_SAI_TCR3; @@ -453,6 +461,8 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, ~FSL_SAI_CR3_TRCE); + + clk_disable_unprepare(sai->bus_clk); } static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { @@ -585,7 +595,8 @@ static int fsl_sai_probe(struct platform_device *pdev) struct fsl_sai *sai; struct resource *res; void __iomem *base; - int irq, ret; + char tmp[8]; + int irq, ret, i; sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); if (!sai) @@ -608,12 +619,35 @@ static int fsl_sai_probe(struct platform_device *pdev) return PTR_ERR(base); sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "sai", base, &fsl_sai_regmap_config); + "bus", base, &fsl_sai_regmap_config); + + /* Compatible with old DTB cases */ + if (IS_ERR(sai->regmap)) + sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + "sai", base, &fsl_sai_regmap_config); if (IS_ERR(sai->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); return PTR_ERR(sai->regmap); } + /* No error out for old DTB cases but only mark the clock NULL */ + sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(sai->bus_clk)) { + dev_err(&pdev->dev, "failed to get bus clock: %ld\n", + PTR_ERR(sai->bus_clk)); + sai->bus_clk = NULL; + } + + for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { + sprintf(tmp, "mclk%d", i + 1); + sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); + if (IS_ERR(sai->mclk_clk[i])) { + dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", + i + 1, PTR_ERR(sai->mclk_clk[i])); + sai->mclk_clk[i] = NULL; + } + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 677670d62fcd..0e6c9f595d75 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -119,6 +119,8 @@ #define FSL_SAI_CLK_MAST2 2 #define FSL_SAI_CLK_MAST3 3 +#define FSL_SAI_MCLK_MAX 3 + /* SAI data transfer numbers per DMA request */ #define FSL_SAI_MAXBURST_TX 6 #define FSL_SAI_MAXBURST_RX 6 @@ -126,6 +128,8 @@ struct fsl_sai { struct platform_device *pdev; struct regmap *regmap; + struct clk *bus_clk; + struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; bool big_endian_regs; bool big_endian_data; From 2b0db996ba2d9b833c2bd2d73cbf301abe11c60e Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 15 Mar 2014 13:44:09 +0100 Subject: [PATCH 0148/1034] ASoC: fsl-ssi: Remove fsl_ssi_setup fsl_ssi_set_dai_fmt() manages most of the register setup routines now. fsl_ssi_setup() makes the same as fsl_ssi_set_dai_fmt() but it relies on DT properties. In most cases the settings of fsl_ssi_setup() are already overwritten by fsl_ssi_set_dai_fmt() when it is called by the soc-core when a sound card is added. As these settings depend on the combination of codec and cpu DAI, this should really be done by sound cards. This patch removes fsl_ssi_setup() and adds the missing register setups to fsl_ssi_set_dai_fmt(). It also removes all calls to fsl_ssi_setup(). Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 143 +++++++++++----------------------------- 1 file changed, 39 insertions(+), 104 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..144934eb9463 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -642,96 +642,6 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); } -static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) -{ - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - u8 wm; - int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; - - fsl_ssi_setup_reg_vals(ssi_private); - - if (ssi_private->imx_ac97) - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; - else - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; - - /* - * Section 16.5 of the MPC8610 reference manual says that the SSI needs - * to be disabled before updating the registers we set here. - */ - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); - - /* - * Program the SSI into I2S Slave Non-Network Synchronous mode. Also - * enable the transmit and receive FIFO. - * - * FIXME: Little-endian samples require a different shift dir - */ - write_ssi_mask(&ssi->scr, - CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, - CCSR_SSI_SCR_TFR_CLK_DIS | - ssi_private->i2s_mode | - (synchronous ? CCSR_SSI_SCR_SYN : 0)); - - write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI | - CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr); - - write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI | - CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr); - - /* - * The DC and PM bits are only used if the SSI is the clock master. - */ - - /* - * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't - * use FIFO 1. We program the transmit water to signal a DMA transfer - * if there are only two (or fewer) elements left in the FIFO. Two - * elements equals one frame (left channel, right channel). This value, - * however, depends on the depth of the transmit buffer. - * - * We set the watermark on the same level as the DMA burstsize. For - * fiq it is probably better to use the biggest possible watermark - * size. - */ - if (ssi_private->use_dma) - wm = ssi_private->fifo_depth - 2; - else - wm = ssi_private->fifo_depth; - - write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | - CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), - &ssi->sfcsr); - - /* - * For ac97 interrupts are enabled with the startup of the substream - * because it is also running without an active substream. Normally SSI - * is only enabled when there is a substream. - */ - if (ssi_private->imx_ac97) - fsl_ssi_setup_ac97(ssi_private); - - /* - * Set a default slot number so that there is no need for those common - * cases like I2S mode to call the extra set_tdm_slot() any more. - */ - if (!ssi_private->imx_ac97) { - write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); - write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); - } - - if (ssi_private->use_dual_fifo) { - write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); - write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); - write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); - } - - return 0; -} - - /** * fsl_ssi_startup: create a new substream * @@ -748,12 +658,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, snd_soc_dai_get_drvdata(rtd->cpu_dai); unsigned long flags; - /* First, we only do fsl_ssi_setup() when SSI is going to be active. - * Second, fsl_ssi_setup was already called by ac97_init earlier if - * the driver is in ac97 mode. - */ if (!dai->active && !ssi_private->imx_ac97) { - fsl_ssi_setup(ssi_private); spin_lock_irqsave(&ssi_private->baudclk_lock, flags); ssi_private->baudclk_locked = false; spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); @@ -835,6 +740,9 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; u32 strcr = 0, stcr, srcr, scr, mask; + u8 wm; + + fsl_ssi_setup_reg_vals(ssi_private); scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); scr |= CCSR_SSI_SCR_NET; @@ -857,7 +765,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) default: return -EINVAL; } - scr |= ssi_private->i2s_mode; /* Data on rising edge of bclk, frame low, 1clk before data */ strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | @@ -877,9 +784,13 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TXBIT0; break; + case SND_SOC_DAIFMT_AC97: + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL; + break; default: return -EINVAL; } + scr |= ssi_private->i2s_mode; /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -929,6 +840,38 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) write_ssi(srcr, &ssi->srcr); write_ssi(scr, &ssi->scr); + /* + * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't + * use FIFO 1. We program the transmit water to signal a DMA transfer + * if there are only two (or fewer) elements left in the FIFO. Two + * elements equals one frame (left channel, right channel). This value, + * however, depends on the depth of the transmit buffer. + * + * We set the watermark on the same level as the DMA burstsize. For + * fiq it is probably better to use the biggest possible watermark + * size. + */ + if (ssi_private->use_dma) + wm = ssi_private->fifo_depth - 2; + else + wm = ssi_private->fifo_depth; + + write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | + CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), + &ssi->sfcsr); + + if (ssi_private->use_dual_fifo) { + write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, + CCSR_SSI_SRCR_RFEN1); + write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, + CCSR_SSI_STCR_TFEN1); + write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, + CCSR_SSI_SCR_TCH_EN); + } + + if (fmt & SND_SOC_DAIFMT_AC97) + fsl_ssi_setup_ac97(ssi_private); + return 0; } @@ -1184,11 +1127,6 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { static struct fsl_ssi_private *fsl_ac97_data; -static void fsl_ssi_ac97_init(void) -{ - fsl_ssi_setup(fsl_ac97_data); -} - static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { @@ -1547,9 +1485,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) } done: - if (ssi_private->imx_ac97) - fsl_ssi_ac97_init(); - return 0; error_dai: From 07a28dbe7ad8e72868239450ff796c90e621d46f Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 15 Mar 2014 13:44:10 +0100 Subject: [PATCH 0149/1034] ASoC: fsl-ssi: Fix i2s_mode variable setup In fsl_ssi_hw_params() we update the I2S and NET bits using the i2s_mode variable. The fsl_ssi_set_dai_fmt() function only writes the i2s-mode to the i2s_mode variable and not the NET bit. This fixes it by adding that bit to i2s_mode. Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 144934eb9463..fdb123d6817c 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -745,7 +745,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) fsl_ssi_setup_reg_vals(ssi_private); scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); - scr |= CCSR_SSI_SCR_NET; mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | @@ -753,14 +752,15 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) stcr = read_ssi(&ssi->stcr) & ~mask; srcr = read_ssi(&ssi->srcr) & ~mask; + ssi_private->i2s_mode = CCSR_SSI_SCR_NET; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; break; case SND_SOC_DAIFMT_CBM_CFM: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; break; default: return -EINVAL; @@ -785,7 +785,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) CCSR_SSI_STCR_TXBIT0; break; case SND_SOC_DAIFMT_AC97: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL; break; default: return -EINVAL; From 74a1672068c7f52f1525a5fca17cdc1ed6961239 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:30 +0100 Subject: [PATCH 0150/1034] ASoC: ams-delta: Convert to table based DAPM and control setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/ams-delta.c | 64 +++++++++++++------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 56a5219c0a00..2ac0a0c3b570 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -38,7 +38,6 @@ #include "omap-mcbsp.h" #include "../codecs/cx20442.h" - /* Board specific DAPM widgets */ static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { /* Handset */ @@ -90,17 +89,23 @@ static const unsigned short ams_delta_audio_mode_pins[] = { static unsigned short ams_delta_audio_agc; +/* + * Used for passing a codec structure pointer + * from the board initialization code to the tty line discipline. + */ +static struct snd_soc_codec *cx20442_codec; + static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ - if (!codec->hw_write) + if (!cx20442_codec->hw_write) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->items) @@ -166,8 +171,8 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; unsigned short pins, mode; pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << @@ -270,12 +275,6 @@ static void cx81801_timeout(unsigned long data) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); } -/* - * Used for passing a codec structure pointer - * from the board initialization code to the tty line discipline. - */ -static struct snd_soc_codec *cx20442_codec; - /* Line discipline .open() */ static int cx81801_open(struct tty_struct *tty) { @@ -302,7 +301,7 @@ static int cx81801_open(struct tty_struct *tty) static void cx81801_close(struct tty_struct *tty) { struct snd_soc_codec *codec = tty->disc_data; - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_dapm_context *dapm = &codec->card->dapm; del_timer_sync(&cx81801_timer); @@ -475,15 +474,14 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = &card->dapm; int ret; /* Codec is ready, now add/activate board specific controls */ /* Store a pointer to the codec structure for tty ldisc use */ - cx20442_codec = codec; + cx20442_codec = rtd->codec; /* Set up digital mute if not provided by the codec */ if (!codec_dai->driver->ops) { @@ -520,25 +518,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } - /* Add board specific DAPM widgets and routes */ - ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, - ARRAY_SIZE(ams_delta_dapm_widgets)); - if (ret) { - dev_warn(card->dev, - "Failed to register DAPM controls, " - "will continue without any.\n"); - return 0; - } - - ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, - ARRAY_SIZE(ams_delta_audio_map)); - if (ret) { - dev_warn(card->dev, - "Failed to set up DAPM routes, " - "will continue with codec default map.\n"); - return 0; - } - /* Set up initial pin constellation */ snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); snd_soc_dapm_enable_pin(dapm, "Earpiece"); @@ -547,14 +526,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_disable_pin(dapm, "AGCIN"); snd_soc_dapm_disable_pin(dapm, "AGCOUT"); - /* Add virtual switch */ - ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls, - ARRAY_SIZE(ams_delta_audio_controls)); - if (ret) - dev_warn(card->dev, - "Failed to register audio mode control, " - "will continue without it.\n"); - return 0; } @@ -576,6 +547,13 @@ static struct snd_soc_card ams_delta_audio_card = { .owner = THIS_MODULE, .dai_link = &ams_delta_dai_link, .num_links = 1, + + .controls = ams_delta_audio_controls, + .num_controls = ARRAY_SIZE(ams_delta_audio_controls), + .dapm_widgets = ams_delta_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ams_delta_dapm_widgets), + .dapm_routes = ams_delta_audio_map, + .num_dapm_routes = ARRAY_SIZE(ams_delta_audio_map), }; /* Module init/exit */ From 81fc5dd4d19faa3dda886910cb8fdad639fa828b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:33 +0100 Subject: [PATCH 0151/1034] ASoC: omap: rx51: Convert to table based control and DAPM setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/rx51.c | 47 +++++++------------------------------------ 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 7fb3d4b10370..2b4641123142 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -237,9 +237,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), SND_SOC_DAPM_MIC("HS Mic", NULL), SND_SOC_DAPM_LINE("FM Transmitter", NULL), -}; - -static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = { SND_SOC_DAPM_SPK("Earphone", NULL), }; @@ -253,9 +250,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"DMic Rate 64", NULL, "Mic Bias"}, {"Mic Bias", NULL, "DMic"}, -}; -static const struct snd_soc_dapm_route audio_mapb[] = { {"b LINE2R", NULL, "MONO_LOUT"}, {"Earphone", NULL, "b HPLOUT"}, @@ -281,9 +276,6 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { SOC_ENUM_EXT("Jack Function", rx51_enum[2], rx51_get_jack, rx51_set_jack), SOC_DAPM_PIN_SWITCH("FM Transmitter"), -}; - -static const struct snd_kcontrol_new aic34_rx51_controlsb[] = { SOC_DAPM_PIN_SWITCH("Earphone"), }; @@ -298,19 +290,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "MIC3R"); snd_soc_dapm_nc_pin(dapm, "LINE1R"); - /* Add RX-51 specific controls */ - err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls, - ARRAY_SIZE(aic34_rx51_controls)); - if (err < 0) - return err; - - /* Add RX-51 specific widgets */ - snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets, - ARRAY_SIZE(aic34_dapm_widgets)); - - /* Set up RX-51 specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - err = tpa6130a2_add_controls(codec); if (err < 0) return err; @@ -333,24 +312,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm) -{ - int err; - - err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb, - ARRAY_SIZE(aic34_rx51_controlsb)); - if (err < 0) - return err; - - err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb, - ARRAY_SIZE(aic34_dapm_widgetsb)); - if (err < 0) - return 0; - - return snd_soc_dapm_add_routes(dapm, audio_mapb, - ARRAY_SIZE(audio_mapb)); -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link rx51_dai[] = { { @@ -371,7 +332,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = { { .name = "TLV320AIC34b", .codec_name = "tlv320aic3x-codec.2-0019", - .init = rx51_aic34b_init, }, }; @@ -392,6 +352,13 @@ static struct snd_soc_card rx51_sound_card = { .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), .codec_conf = rx51_codec_conf, .num_configs = ARRAY_SIZE(rx51_codec_conf), + + .controls = aic34_rx51_controls, + .num_controls = ARRAY_SIZE(aic34_rx51_controls), + .dapm_widgets = aic34_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), }; static struct platform_device *rx51_snd_device; From b2e69054ea1a36f2c1ace15a55240937aa091cba Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:34 +0100 Subject: [PATCH 0152/1034] ASoC: omap3pandora: Convert to table based DAPM setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/omap3pandora.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index cf604a2faa18..02181bb70400 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -121,7 +121,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, * |A| <~~clk~~+ * |P| <--- TWL4030 <--------- Line In and MICs */ -static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { +static const struct snd_soc_dapm_widget omap3pandora_dapm_widgets[] = { SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0, omap3pandora_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -130,22 +130,18 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), -}; -static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { SND_SOC_DAPM_MIC("Mic (internal)", NULL), SND_SOC_DAPM_MIC("Mic (external)", NULL), SND_SOC_DAPM_LINE("Line In", NULL), }; -static const struct snd_soc_dapm_route omap3pandora_out_map[] = { +static const struct snd_soc_dapm_route omap3pandora_map[] = { {"PCM DAC", NULL, "APLL Enable"}, {"Headphone Amplifier", NULL, "PCM DAC"}, {"Line Out", NULL, "PCM DAC"}, {"Headphone Jack", NULL, "Headphone Amplifier"}, -}; -static const struct snd_soc_dapm_route omap3pandora_in_map[] = { {"AUXL", NULL, "Line In"}, {"AUXR", NULL, "Line In"}, @@ -160,7 +156,6 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* All TWL4030 output pins are floating */ snd_soc_dapm_nc_pin(dapm, "EARPIECE"); @@ -174,20 +169,13 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "HFR"); snd_soc_dapm_nc_pin(dapm, "VIBRA"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets, - ARRAY_SIZE(omap3pandora_out_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, - ARRAY_SIZE(omap3pandora_out_map)); + return 0; } static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* Not comnnected */ snd_soc_dapm_nc_pin(dapm, "HSMIC"); @@ -195,13 +183,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, - ARRAY_SIZE(omap3pandora_in_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, - ARRAY_SIZE(omap3pandora_in_map)); + return 0; } static struct snd_soc_ops omap3pandora_ops = { @@ -241,6 +223,11 @@ static struct snd_soc_card snd_soc_card_omap3pandora = { .owner = THIS_MODULE, .dai_link = omap3pandora_dai, .num_links = ARRAY_SIZE(omap3pandora_dai), + + .dapm_widgets = omap3pandora_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(omap3pandora_dapm_widgets), + .dapm_routes = omap3pandora_map, + .num_dapm_routes = ARRAY_SIZE(omap3pandora_map), }; static struct platform_device *omap3pandora_snd_device; From 4c9185be5e8eefd10b0f172e794b108697d86985 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 27 Mar 2014 15:55:47 +0800 Subject: [PATCH 0153/1034] ASoC: rt5640: Move cache sync() to resume() The patch fixes the defect in case of resume which doesn't sync the cache. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..4a7bd0a16912 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1890,11 +1890,9 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, static int rt5640_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_STANDBY: if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { - regcache_cache_only(rt5640->regmap, false); snd_soc_update_bits(codec, RT5640_PWR_ANLG1, RT5640_PWR_VREF1 | RT5640_PWR_MB | RT5640_PWR_BG | RT5640_PWR_VREF2, @@ -1904,7 +1902,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, RT5640_PWR_ANLG1, RT5640_PWR_FV1 | RT5640_PWR_FV2, RT5640_PWR_FV1 | RT5640_PWR_FV2); - regcache_sync(rt5640->regmap); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); snd_soc_update_bits(codec, RT5640_MICBIAS, @@ -1979,6 +1976,9 @@ static int rt5640_resume(struct snd_soc_codec *codec) msleep(400); } + regcache_cache_only(rt5640->regmap, false); + regcache_sync(rt5640->regmap); + return 0; } #else From 9bccae733b8d0e281729464267191103c09b3d13 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 27 Mar 2014 19:34:51 +0800 Subject: [PATCH 0154/1034] ASoC: rt5640: Correct the judgement of data length The patch corrects the judgement of data length. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 4a7bd0a16912..f0717db3e935 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1622,16 +1622,16 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", bclk_ms, pre_div, dai->id); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val_len |= RT5640_I2S_DL_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val_len |= RT5640_I2S_DL_24; break; - case SNDRV_PCM_FORMAT_S8: + case 8: val_len |= RT5640_I2S_DL_8; break; default: From 71d97a7943017faf03707836d00a260a108f4c89 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 10:46:18 +0800 Subject: [PATCH 0155/1034] ASoC: rt5640: Use the platform data for DMIC settings The patch uses the platform data for DMIC settings. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- include/sound/rt5640.h | 4 ++ sound/soc/codecs/rt5640.c | 77 ++++++++++++--------------------------- 2 files changed, 27 insertions(+), 54 deletions(-) diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h index 27cc75ed67f8..59d26dd81e45 100644 --- a/include/sound/rt5640.h +++ b/include/sound/rt5640.h @@ -16,6 +16,10 @@ struct rt5640_platform_data { bool in1_diff; bool in2_diff; + bool dmic_en; + bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */ + bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */ + int ldo1_en; /* GPIO for LDO1_EN */ }; diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f0717db3e935..6ede622ad44f 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -872,54 +872,6 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP, static const struct snd_kcontrol_new rt5640_sdi_mux = SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); -static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, - RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK, - RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA); - snd_soc_update_bits(codec, RT5640_DMIC, - RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK | - RT5640_DMIC_1_DP_MASK, - RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING | - RT5640_DMIC_1_DP_IN1P); - break; - - default: - return 0; - } - - return 0; -} - -static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, - RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK, - RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA); - snd_soc_update_bits(codec, RT5640_DMIC, - RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK | - RT5640_DMIC_2_DP_MASK, - RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING | - RT5640_DMIC_2_DP_IN1N); - break; - - default: - return 0; - } - - return 0; -} - static void hp_amp_power_on(struct snd_soc_codec *codec) { struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); @@ -1054,12 +1006,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, set_dmic_clk, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, - RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event, - SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, - RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event, - SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, RT5640_DMIC_1_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, RT5640_DMIC_2_EN_SFT, 0, + NULL, 0), /* Boost */ SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2, RT5640_PWR_BST1_BIT, 0, NULL, 0), @@ -2187,6 +2137,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, RT5640_IN_DF2, RT5640_IN_DF2); + if (rt5640->pdata.dmic_en) { + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); + + if (rt5640->pdata.dmic1_data_pin) { + regmap_update_bits(rt5640->regmap, RT5640_DMIC, + RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3); + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA); + } + + if (rt5640->pdata.dmic2_data_pin) { + regmap_update_bits(rt5640->regmap, RT5640_DMIC, + RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4); + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA); + } + } + rt5640->hp_mute = 1; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, From 2f2a714c1bed2702e5abf55381c03ccdf7b0fd06 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:25 +0800 Subject: [PATCH 0156/1034] ASoC: rt5640: Remove the pre-allocated size of reg_default In order to prevent the redundant memory usage, the pre-allocated size of reg_default should be remove. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 6ede622ad44f..84ee7ef8eb17 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -59,7 +59,7 @@ static struct reg_default init_list[] = { }; #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) -static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = { +static const struct reg_default rt5640_reg[] = { { 0x00, 0x000e }, { 0x01, 0xc8c8 }, { 0x02, 0xc8c8 }, From 218a3f963822aca1d38b0175b6454fe53d15c2dd Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:26 +0800 Subject: [PATCH 0157/1034] ASoC: rt5640: Rename the function of clock checking In order to identify clearly, the patch renames the function "check_sysclk1_source" to "is_sys_clk_from_pll". Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 84ee7ef8eb17..19634d0992bc 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -480,7 +480,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, return idx; } -static int check_sysclk1_source(struct snd_soc_dapm_widget *source, +static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { unsigned int val; @@ -1273,22 +1273,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, {"Stereo ADC MIXL", NULL, "Stereo Filter"}, - {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, + {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, {"Stereo ADC MIXR", NULL, "Stereo Filter"}, - {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, + {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, {"Mono ADC MIXL", NULL, "Mono Left Filter"}, - {"Mono Left Filter", NULL, "PLL1", check_sysclk1_source}, + {"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, {"Mono ADC MIXR", NULL, "Mono Right Filter"}, - {"Mono Right Filter", NULL, "PLL1", check_sysclk1_source}, + {"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"IF2 ADC L", NULL, "Mono ADC MIXL"}, {"IF2 ADC R", NULL, "Mono ADC MIXR"}, @@ -1377,13 +1377,13 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, {"DAC L1", NULL, "Stereo DAC MIXL"}, - {"DAC L1", NULL, "PLL1", check_sysclk1_source}, + {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R1", NULL, "Stereo DAC MIXR"}, - {"DAC R1", NULL, "PLL1", check_sysclk1_source}, + {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC L2", NULL, "Mono DAC MIXL"}, - {"DAC L2", NULL, "PLL1", check_sysclk1_source}, + {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R2", NULL, "Mono DAC MIXR"}, - {"DAC R2", NULL, "PLL1", check_sysclk1_source}, + {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, {"SPK MIXL", "INL Switch", "INL VOL"}, From acf04e639bba2270fd07e161fa984234591ef43b Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:27 +0800 Subject: [PATCH 0158/1034] ASoC: rt5640: Remove the unused or incorrect setting of clock source The patch removes the unused or incorrect setting of clock source. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 8 +------- sound/soc/codecs/rt5640.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 19634d0992bc..4c866135e40f 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -487,7 +487,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, val = snd_soc_read(source->codec, RT5640_GLB_CLK); val &= RT5640_SCLK_SRC_MASK; - if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T) + if (val == RT5640_SCLK_SRC_PLL1) return 1; else return 0; @@ -1694,12 +1694,6 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, case RT5640_SCLK_S_PLL1: reg_val |= RT5640_SCLK_SRC_PLL1; break; - case RT5640_SCLK_S_PLL1_TK: - reg_val |= RT5640_SCLK_SRC_PLL1T; - break; - case RT5640_SCLK_S_RCCLK: - reg_val |= RT5640_SCLK_SRC_RCCLK; - break; default: dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); return -EINVAL; diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 5e8df25a13f3..cbd07b5f8060 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -976,8 +976,6 @@ #define RT5640_SCLK_SRC_SFT 14 #define RT5640_SCLK_SRC_MCLK (0x0 << 14) #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) -#define RT5640_SCLK_SRC_PLL1T (0x2 << 14) -#define RT5640_SCLK_SRC_RCCLK (0x3 << 14) /* 15MHz */ #define RT5640_PLL1_SRC_MASK (0x3 << 12) #define RT5640_PLL1_SRC_SFT 12 #define RT5640_PLL1_SRC_MCLK (0x0 << 12) From bc49e462cd6ded128cc6dbb6775de4a4c3d6bbc8 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:28 +0800 Subject: [PATCH 0159/1034] ASoC: rt5640: Remove the unused field in private data The patch removes the unused field in private data. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index cbd07b5f8060..d7bd525caf85 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -2095,7 +2095,6 @@ struct rt5640_priv { int pll_in; int pll_out; - int dmic_en; bool hp_mute; }; From 3441e524293c5e8d640488e343f2eb2bcc944108 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:29 +0800 Subject: [PATCH 0160/1034] ASoC: rt5640: Remove the unnecessary parentheses The patch removes the unnecessary parentheses. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 4c866135e40f..b6a02c16f100 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2110,7 +2110,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, } regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); - if ((val != RT5640_DEVICE_ID)) { + if (val != RT5640_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %x is not rt5640/39\n", val); return -ENODEV; From 09caf300540c4a610dbe6e46afdab18f365be7e7 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Mon, 31 Mar 2014 10:21:10 +0800 Subject: [PATCH 0161/1034] ASoC: rt5640: Change the setting method of idle_bias_off The patch moves the idle_bias_off setting to struct "soc_codec_dev_rt5640". Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index b6a02c16f100..a7db7ef38cfc 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1879,7 +1879,6 @@ static int rt5640_probe(struct snd_soc_codec *codec) rt5640->codec = codec; - codec->dapm.idle_bias_off = 1; rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); @@ -1988,6 +1987,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { .suspend = rt5640_suspend, .resume = rt5640_resume, .set_bias_level = rt5640_set_bias_level, + .idle_bias_off = true, .controls = rt5640_snd_controls, .num_controls = ARRAY_SIZE(rt5640_snd_controls), .dapm_widgets = rt5640_dapm_widgets, From 022d21f004c14db2151d08143a544b292324d099 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Tue, 8 Apr 2014 19:40:00 +0800 Subject: [PATCH 0162/1034] ASoC: rt5640: add rt5639 support This patch adds the rt5639 support Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 286 ++++++++++++++++++++++++++++---------- sound/soc/codecs/rt5640.h | 3 + 2 files changed, 213 insertions(+), 76 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a7db7ef38cfc..a20781eda719 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -398,18 +398,13 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), - /* MONO Output Control */ - SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, - RT5640_L_MUTE_SFT, 1, 1), + /* DAC Digital Volume */ SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL, RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1), SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv), - SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, - RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, - 175, 0, dac_vol_tlv), /* IN1/IN2 Control */ SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, RT5640_BST_SFT1, 8, 0, bst_tlv), @@ -441,6 +436,15 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum), }; +static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = { + /* MONO Output Control */ + SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, RT5640_L_MUTE_SFT, + 1, 1), + + SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, + RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv), +}; + /** * set_dmic_clk - Set parameter of dmic. * @@ -554,6 +558,20 @@ static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = { RT5640_M_ANC_DAC_R_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_sto_dac_l_mix[] = { + SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_L1_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_L2_SFT, 1, 1), +}; + +static const struct snd_kcontrol_new rt5639_sto_dac_r_mix[] = { + SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_R1_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_R2_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = { SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER, RT5640_M_DAC_L1_MONO_L_SFT, 1, 1), @@ -676,6 +694,30 @@ static const struct snd_kcontrol_new rt5640_out_r_mix[] = { RT5640_M_DAC_R1_OM_R_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_out_l_mix[] = { + SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER, + RT5640_M_BST1_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER, + RT5640_M_IN_L_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER, + RT5640_M_RM_L_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER, + RT5640_M_DAC_L1_OM_L_SFT, 1, 1), +}; + +static const struct snd_kcontrol_new rt5639_out_r_mix[] = { + SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_BST4_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_BST1_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER, + RT5640_M_IN_R_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER, + RT5640_M_RM_R_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_DAC_R1_OM_R_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_spo_l_mix[] = { SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER, RT5640_M_DAC_R1_SPM_L_SFT, 1, 1), @@ -707,6 +749,13 @@ static const struct snd_kcontrol_new rt5640_hpo_mix[] = { RT5640_M_HPVOL_HM_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_hpo_mix[] = { + SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER, + RT5640_M_DAC1_HM_SFT, 1, 1), + SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER, + RT5640_M_HPVOL_HM_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_lout_mix[] = { SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER, RT5640_M_DAC_L1_LM_SFT, 1, 1), @@ -1096,26 +1145,15 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), - /* Audio DSP */ - SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), - /* ANC */ - SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), + /* Output Side */ /* DAC mixer before sound effect */ SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)), SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)), - /* DAC2 channel Mux */ - SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5640_dac_l2_mux), - SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5640_dac_r2_mux), + /* DAC Mixer */ - SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, - rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), - SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, - rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)), SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, @@ -1127,21 +1165,14 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { /* DACs */ SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L1_BIT, 0), - SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, - RT5640_PWR_DAC_L2_BIT, 0), SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R1_BIT, 0), - SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, - RT5640_PWR_DAC_R2_BIT, 0), + /* SPK/OUT Mixer */ SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT, 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)), - SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, - 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), - SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, - 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), /* Ouput Volume */ SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL, RT5640_PWR_SV_L_BIT, 0, NULL, 0), @@ -1160,16 +1191,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)), SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)), - SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, - rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), - SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, - rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0, rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)), - SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, - rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), - SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, - RT5640_PWR_MA_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, @@ -1201,10 +1224,69 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HPOR"), SND_SOC_DAPM_OUTPUT("LOUTL"), SND_SOC_DAPM_OUTPUT("LOUTR"), +}; + +static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { + /* Audio DSP */ + SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), + /* ANC */ + SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* DAC2 channel Mux */ + SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_l2_mux), + SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_r2_mux), + + SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, + rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), + SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, + rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), + + SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R2_BIT, + 0), + SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L2_BIT, + 0), + + SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, + 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), + SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, + 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), + + SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, + rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), + SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, + rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), + + SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, + rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), + SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, + RT5640_PWR_MA_BIT, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("MONOP"), SND_SOC_DAPM_OUTPUT("MONON"), }; +static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, + rt5639_sto_dac_l_mix, ARRAY_SIZE(rt5639_sto_dac_l_mix)), + SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, + rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)), + + SND_SOC_DAPM_SUPPLY("DAC L2 Filter", RT5640_PWR_DIG1, + RT5640_PWR_DAC_L2_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC R2 Filter", RT5640_PWR_DIG1, + RT5640_PWR_DAC_R2_BIT, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, + 0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)), + SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, + 0, rt5639_out_r_mix, ARRAY_SIZE(rt5639_out_r_mix)), + + SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, + rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), + SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, + rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), +}; + static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"IN1P", NULL, "LDO2"}, {"IN2P", NULL, "LDO2"}, @@ -1346,71 +1428,38 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, - {"ANC", NULL, "Stereo ADC MIXL"}, - {"ANC", NULL, "Stereo ADC MIXR"}, - - {"Audio DSP", NULL, "DAC MIXL"}, - {"Audio DSP", NULL, "DAC MIXR"}, - - {"DAC L2 Mux", "IF2", "IF2 DAC L"}, - {"DAC L2 Mux", "Base L/R", "Audio DSP"}, - - {"DAC R2 Mux", "IF2", "IF2 DAC R"}, - {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, - {"Stereo DAC MIXL", "ANC Switch", "ANC"}, {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, - {"Stereo DAC MIXR", "ANC Switch", "ANC"}, {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, - {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, - {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, {"DAC L1", NULL, "Stereo DAC MIXL"}, {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R1", NULL, "Stereo DAC MIXR"}, {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, - {"DAC L2", NULL, "Mono DAC MIXL"}, - {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, - {"DAC R2", NULL, "Mono DAC MIXR"}, - {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, {"SPK MIXL", "INL Switch", "INL VOL"}, {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, - {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, {"SPK MIXR", "INR Switch", "INR VOL"}, {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, - {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, - {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, {"OUT MIXL", "BST1 Switch", "BST1"}, {"OUT MIXL", "INL Switch", "INL VOL"}, {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, - {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, - {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, - {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, {"OUT MIXR", "BST2 Switch", "BST2"}, {"OUT MIXR", "BST1 Switch", "BST1"}, {"OUT MIXR", "INR Switch", "INR VOL"}, {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, - {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, - {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, {"SPKVOL L", NULL, "SPK MIXL"}, @@ -1429,11 +1478,9 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, {"SPOR MIX", "BST1 Switch", "BST1"}, - {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, {"HPO MIX L", NULL, "HP L Amp"}, - {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, {"HPO MIX R", NULL, "HP R Amp"}, @@ -1443,12 +1490,6 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, - {"Mono MIX", "DAC R2 Switch", "DAC R2"}, - {"Mono MIX", "DAC L2 Switch", "DAC L2"}, - {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, - {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, - {"Mono MIX", "BST1 Switch", "BST1"}, - {"HP Amp", NULL, "HPO MIX L"}, {"HP Amp", NULL, "HPO MIX R"}, @@ -1473,11 +1514,82 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"HPOR", NULL, "HP R Playback"}, {"LOUTL", NULL, "LOUT MIX"}, {"LOUTR", NULL, "LOUT MIX"}, +}; + +static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = { + {"ANC", NULL, "Stereo ADC MIXL"}, + {"ANC", NULL, "Stereo ADC MIXR"}, + + {"Audio DSP", NULL, "DAC MIXL"}, + {"Audio DSP", NULL, "DAC MIXR"}, + + {"DAC L2 Mux", "IF2", "IF2 DAC L"}, + {"DAC L2 Mux", "Base L/R", "Audio DSP"}, + + {"DAC R2 Mux", "IF2", "IF2 DAC R"}, + + {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + {"Stereo DAC MIXL", "ANC Switch", "ANC"}, + {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"Stereo DAC MIXR", "ANC Switch", "ANC"}, + + {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, + + {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, + + {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + + {"DAC L2", NULL, "Mono DAC MIXL"}, + {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, + {"DAC R2", NULL, "Mono DAC MIXR"}, + {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, + + {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, + {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, + + {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, + {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, + + {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, + {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, + + {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, + {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, + + {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, + {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, + + {"Mono MIX", "DAC R2 Switch", "DAC R2"}, + {"Mono MIX", "DAC L2 Switch", "DAC L2"}, + {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, + {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, + {"Mono MIX", "BST1 Switch", "BST1"}, + {"MONOP", NULL, "Mono MIX"}, {"MONON", NULL, "Mono MIX"}, {"MONOP", NULL, "Improve MONO Amp Drv"}, }; +static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = { + {"Stereo DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"Stereo DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, + + {"Mono DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"Mono DAC MIXL", "DAC R2 Switch", "IF2 DAC R"}, + + {"Mono DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, + {"Mono DAC MIXR", "DAC L2 Switch", "IF2 DAC L"}, + + {"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"}, + + {"IF2 DAC L", NULL, "DAC L2 Filter"}, + {"IF2 DAC R", NULL, "DAC R2 Filter"}, +}; + static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) { int ret = 0, val; @@ -1885,6 +1997,28 @@ static int rt5640_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); + switch (snd_soc_read(codec, RT5640_RESET)) { + case RT5640_RESET_ID: + snd_soc_add_codec_controls(codec, + rt5640_specific_snd_controls, + ARRAY_SIZE(rt5640_specific_snd_controls)); + snd_soc_dapm_new_controls(&codec->dapm, + rt5640_specific_dapm_widgets, + ARRAY_SIZE(rt5640_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5640_specific_dapm_routes, + ARRAY_SIZE(rt5640_specific_dapm_routes)); + break; + case RT5639_RESET_ID: + snd_soc_dapm_new_controls(&codec->dapm, + rt5639_specific_dapm_widgets, + ARRAY_SIZE(rt5639_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5639_specific_dapm_routes, + ARRAY_SIZE(rt5639_specific_dapm_routes)); + break; + } + return 0; } diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index d7bd525caf85..3b50459a83b4 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -14,6 +14,9 @@ #include +#define RT5639_RESET_ID 0x0008 +#define RT5640_RESET_ID 0x000c + /* Info */ #define RT5640_RESET 0x00 #define RT5640_VENDOR_ID 0xfd From b0c278469777b75d0af3b5718369084acb71c344 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 10 Apr 2014 10:57:34 +0800 Subject: [PATCH 0163/1034] ASoC: rt5640: Add the string "rt5639" to the list of I2C device IDs The patch adds the string "rt5639" to the list of I2C device IDs. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a20781eda719..6674372be12c 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1,5 +1,5 @@ /* - * rt5640.c -- RT5640 ALSA SoC audio codec driver + * rt5640.c -- RT5640/RT5639 ALSA SoC audio codec driver * * Copyright 2011 Realtek Semiconductor Corp. * Author: Johnny Hsu @@ -2148,6 +2148,7 @@ static const struct regmap_config rt5640_regmap = { static const struct i2c_device_id rt5640_i2c_id[] = { { "rt5640", 0 }, + { "rt5639", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); @@ -2316,6 +2317,6 @@ static struct i2c_driver rt5640_i2c_driver = { }; module_i2c_driver(rt5640_i2c_driver); -MODULE_DESCRIPTION("ASoC RT5640 driver"); +MODULE_DESCRIPTION("ASoC RT5640/RT5639 driver"); MODULE_AUTHOR("Johnny Hsu "); MODULE_LICENSE("GPL v2"); From 908b7032a8b5cb7110beac213f7d3058097fa5aa Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 10 Apr 2014 10:57:35 +0800 Subject: [PATCH 0164/1034] ASoC: rt5640: Add the info of rt5639 to the binding document The patch adds the info of rt5639 to the binding document. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rt5640.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt index 068a1141b06f..bac4d9ac1edc 100644 --- a/Documentation/devicetree/bindings/sound/rt5640.txt +++ b/Documentation/devicetree/bindings/sound/rt5640.txt @@ -1,10 +1,10 @@ -RT5640 audio CODEC +RT5640/RT5639 audio CODEC This device supports I2C only. Required properties: -- compatible : "realtek,rt5640". +- compatible : One of "realtek,rt5640" or "realtek,rt5639". - reg : The I2C address of the device. @@ -18,7 +18,7 @@ Optional properties: - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. -Pins on the device (for linking into audio routes): +Pins on the device (for linking into audio routes) for RT5639/RT5640: * DMIC1 * DMIC2 @@ -31,13 +31,16 @@ Pins on the device (for linking into audio routes): * HPOR * LOUTL * LOUTR - * MONOP - * MONON * SPOLP * SPOLN * SPORP * SPORN +Additional pins on the device for RT5640: + + * MONOP + * MONON + Example: rt5640 { From b87704cef258a4f44ab1386a70b7628ec3cefd36 Mon Sep 17 00:00:00 2001 From: Rongjun Ying Date: Thu, 20 Mar 2014 15:46:19 +0800 Subject: [PATCH 0165/1034] ASoC: sirf: Move the tx rx enable from port to codec, that will not need register sharing The port driver only used to register component and dmaengine pcm. Signed-off-by: Rongjun Ying Signed-off-by: Mark Brown --- sound/soc/codecs/sirf-audio-codec.c | 74 ++++++++++++++++--- sound/soc/codecs/sirf-audio-codec.h | 50 +++++++++++++ sound/soc/sirf/sirf-audio-port.c | 107 ---------------------------- sound/soc/sirf/sirf-audio-port.h | 62 ---------------- 4 files changed, 116 insertions(+), 177 deletions(-) delete mode 100644 sound/soc/sirf/sirf-audio-port.h diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 58e7c1f23771..c5177bc5df82 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { {"Mic input mode mux", "Differential", "MICIN1"}, }; +static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); +} + +static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); +} + +static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, + int channels) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, + AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + if (channels == 1) + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); + else + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); +} + +static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); +} + static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_soc_codec *codec = dai->codec; - u32 val = 0; + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; /* * This is a workaround, When stop playback, @@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (playback) { + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, 0); + sirf_audio_codec_tx_disable(sirf_audio_codec); + } else + sirf_audio_codec_rx_disable(sirf_audio_codec); break; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) - val = IC_HSLEN | IC_HSREN; + if (playback) { + sirf_audio_codec_tx_enable(sirf_audio_codec); + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); + } else + sirf_audio_codec_rx_enable(sirf_audio_codec, + substream->runtime->channels); break; default: return -EINVAL; } - if (playback) - snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, val); return 0; } @@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = AUDIO_IC_CODEC_CTRL3, + .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, .cache_type = REGCACHE_NONE, }; diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h index d4c187b8e54a..ba1adc03839f 100644 --- a/sound/soc/codecs/sirf-audio-codec.h +++ b/sound/soc/codecs/sirf-audio-codec.h @@ -72,4 +72,54 @@ #define IC_RXPGAR 0x7B #define IC_RXPGAL 0x7B +#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F +#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 + +#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_SC_OFFSET) +#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_LC_OFFSET) +#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_HC_OFFSET) + +#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F +#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 + +#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_SC_OFFSET) +#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_LC_OFFSET) +#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_HC_OFFSET) +#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) +#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) + +#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) +#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) +#define AUDIO_PORT_IC_TXFIFO_STS (0x0104) +#define AUDIO_PORT_IC_TXFIFO_INT (0x0108) +#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) + +#define AUDIO_PORT_IC_RXFIFO_OP (0x0110) +#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) +#define AUDIO_PORT_IC_RXFIFO_STS (0x0118) +#define AUDIO_PORT_IC_RXFIFO_INT (0x011C) +#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) + +#define AUDIO_FIFO_START (1 << 0) +#define AUDIO_FIFO_RESET (1 << 1) + +#define AUDIO_FIFO_FULL (1 << 0) +#define AUDIO_FIFO_EMPTY (1 << 1) +#define AUDIO_FIFO_OFLOW (1 << 2) +#define AUDIO_FIFO_UFLOW (1 << 3) + +#define IC_TX_ENABLE (0x03) +#define IC_RX_ENABLE_MONO (0x01) +#define IC_RX_ENABLE_STEREO (0x03) + #endif /*__SIRF_AUDIO_CODEC_H*/ diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c index b04a53f2b4f6..b4afa31b2bc1 100644 --- a/sound/soc/sirf/sirf-audio-port.c +++ b/sound/soc/sirf/sirf-audio-port.c @@ -6,60 +6,15 @@ * Licensed under GPLv2 or later. */ #include -#include -#include #include #include -#include "sirf-audio-port.h" - struct sirf_audio_port { struct regmap *regmap; struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data; }; -static void sirf_audio_port_tx_enable(struct sirf_audio_port *port) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, - IC_TX_ENABLE, IC_TX_ENABLE); -} - -static void sirf_audio_port_tx_disable(struct sirf_audio_port *port) -{ - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, - IC_TX_ENABLE, ~IC_TX_ENABLE); -} - -static void sirf_audio_port_rx_enable(struct sirf_audio_port *port, - int channels) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); - regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - if (channels == 1) - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); - else - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); -} - -static void sirf_audio_port_rx_disable(struct sirf_audio_port *port) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); -} static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) { @@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) return 0; } -static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (playback) - sirf_audio_port_tx_disable(port); - else - sirf_audio_port_rx_disable(port); - break; - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) - sirf_audio_port_tx_enable(port); - else - sirf_audio_port_rx_enable(port, - substream->runtime->channels); - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = { - .trigger = sirf_audio_port_trigger, -}; - static struct snd_soc_dai_driver sirf_audio_port_dai = { .probe = sirf_audio_port_dai_probe, .name = "sirf-audio-port", @@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = { .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &sirf_audio_port_dai_ops, }; static const struct snd_soc_component_driver sirf_audio_port_component = { .name = "sirf-audio-port", }; -static const struct regmap_config sirf_audio_port_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, - .cache_type = REGCACHE_NONE, -}; - static int sirf_audio_port_probe(struct platform_device *pdev) { int ret; struct sirf_audio_port *port; - void __iomem *base; - struct resource *mem_res; port = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_port), GFP_KERNEL); if (!port) return -ENOMEM; - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "no mem resource?\n"); - return -ENODEV; - } - - base = devm_ioremap(&pdev->dev, mem_res->start, - resource_size(mem_res)); - if (base == NULL) - return -ENOMEM; - - port->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_audio_port_regmap_config); - if (IS_ERR(port->regmap)) - return PTR_ERR(port->regmap); - ret = devm_snd_soc_register_component(&pdev->dev, &sirf_audio_port_component, &sirf_audio_port_dai, 1); if (ret) diff --git a/sound/soc/sirf/sirf-audio-port.h b/sound/soc/sirf/sirf-audio-port.h deleted file mode 100644 index f32dc54f4499..000000000000 --- a/sound/soc/sirf/sirf-audio-port.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SiRF Audio port controllers define - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef _SIRF_AUDIO_PORT_H -#define _SIRF_AUDIO_PORT_H - -#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F -#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 -#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 -#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 - -#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_SC_OFFSET) -#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_LC_OFFSET) -#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_HC_OFFSET) - -#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F -#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 -#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 -#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 - -#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_SC_OFFSET) -#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_LC_OFFSET) -#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_HC_OFFSET) -#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) -#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) - -#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) -#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) -#define AUDIO_PORT_IC_TXFIFO_STS (0x0104) -#define AUDIO_PORT_IC_TXFIFO_INT (0x0108) -#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) - -#define AUDIO_PORT_IC_RXFIFO_OP (0x0110) -#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) -#define AUDIO_PORT_IC_RXFIFO_STS (0x0118) -#define AUDIO_PORT_IC_RXFIFO_INT (0x011C) -#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) - -#define AUDIO_FIFO_START (1 << 0) -#define AUDIO_FIFO_RESET (1 << 1) - -#define AUDIO_FIFO_FULL (1 << 0) -#define AUDIO_FIFO_EMPTY (1 << 1) -#define AUDIO_FIFO_OFLOW (1 << 2) -#define AUDIO_FIFO_UFLOW (1 << 3) - -#define IC_TX_ENABLE (0x03) -#define IC_RX_ENABLE_MONO (0x01) -#define IC_RX_ENABLE_STEREO (0x03) - -#endif /*__SIRF_AUDIO_PORT_H*/ From 2439ea1f0f8f4cc98dfae0d1cd5ba88f6c3ee9ad Mon Sep 17 00:00:00 2001 From: Sven Brandau Date: Wed, 2 Apr 2014 10:25:05 +0200 Subject: [PATCH 0166/1034] ASoC: sta350: Add codec driver The TI STA350 is an integrated 2.1-channel power amplifier that is controllable over I2C. This patch adds an ASoC driver for it. At a glance, this chip is very similar to the STA320 for which a driver already exists. In details, however, the register maps contain subtle differences which made a whole new driver easier to write and maintain. [daniel@zonque.org: cleanups, DT property rework, rebased on asoc-next] Signed-off-by: Sven Brandau Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/st,sta350.txt | 107 ++ include/sound/sta350.h | 52 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/sta350.c | 1266 +++++++++++++++++ sound/soc/codecs/sta350.h | 228 +++ 6 files changed, 1660 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/st,sta350.txt create mode 100644 include/sound/sta350.h create mode 100644 sound/soc/codecs/sta350.c create mode 100644 sound/soc/codecs/sta350.h diff --git a/Documentation/devicetree/bindings/sound/st,sta350.txt b/Documentation/devicetree/bindings/sound/st,sta350.txt new file mode 100644 index 000000000000..950188891abd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/st,sta350.txt @@ -0,0 +1,107 @@ +STA350 audio CODEC + +The driver for this device only supports I2C. + +Required properties: + + - compatible: "st,sta350" + - reg: the I2C address of the device for I2C + - reset-gpios: a GPIO spec for the reset pin. If specified, it will be + deasserted before communication to the codec starts. + + - power-down-gpios: a GPIO spec for the power down pin. If specified, + it will be deasserted before communication to the codec + starts. + + - vdd-dig-supply: regulator spec, providing 3.3V + - vdd-pll-supply: regulator spec, providing 3.3V + - vcc-supply: regulator spec, providing 5V - 26V + +Optional properties: + + - st,output-conf: number, Selects the output configuration: + 0: 2-channel (full-bridge) power, 2-channel data-out + 1: 2 (half-bridge). 1 (full-bridge) on-board power + 2: 2 Channel (Full-Bridge) Power, 1 Channel FFX + 3: 1 Channel Mono-Parallel + If parameter is missing, mode 0 will be enabled. + + - st,ch1-output-mapping: Channel 1 output mapping + - st,ch2-output-mapping: Channel 2 output mapping + - st,ch3-output-mapping: Channel 3 output mapping + 0: Channel 1 + 1: Channel 2 + 2: Channel 3 + If parameter is missing, channel 1 is choosen. + + - st,thermal-warning-recover: + If present, thermal warning recovery is enabled. + + - st,thermal-warning-adjustment: + If present, thermal warning adjustment is enabled. + + - st,fault-detect-recovery: + If present, then fault recovery will be enabled. + + - st,ffx-power-output-mode: string + The FFX power output mode selects how the FFX output timing is + configured. Must be one of these values: + - "drop-compensation" + - "tapered-compensation" + - "full-power-mode" + - "variable-drop-compensation" (default) + + - st,drop-compensation-ns: number + Only required for "st,ffx-power-output-mode" == + "variable-drop-compensation". + Specifies the drop compensation in nanoseconds. + The value must be in the range of 0..300, and only + multiples of 20 are allowed. Default is 140ns. + + - st,overcurrent-warning-adjustment: + If present, overcurrent warning adjustment is enabled. + + - st,max-power-use-mpcc: + If present, then MPCC bits are used for MPC coefficients, + otherwise standard MPC coefficients are used. + + - st,max-power-corr: + If present, power bridge correction for THD reduction near maximum + power output is enabled. + + - st,am-reduction-mode: + If present, FFX mode runs in AM reduction mode, otherwise normal + FFX mode is used. + + - st,odd-pwm-speed-mode: + If present, PWM speed mode run on odd speed mode (341.3 kHz) on all + channels. If not present, normal PWM spped mode (384 kHz) will be used. + + - st,distortion-compensation: + If present, distortion compensation variable uses DCC coefficient. + If not present, preset DC coefficient is used. + + - st,invalid-input-detect-mute: + If not present, automatic invalid input detect mute is enabled. + + + +Example: + +codec: sta350@38 { + compatible = "st,sta350"; + reg = <0x1c>; + reset-gpios = <&gpio1 19 0>; + power-down-gpios = <&gpio1 16 0>; + st,output-conf = <0x3>; // set output to 2-channel + // (full-bridge) power, + // 2-channel data-out + st,ch1-output-mapping = <0>; // set channel 1 output ch 1 + st,ch2-output-mapping = <0>; // set channel 2 output ch 1 + st,ch3-output-mapping = <0>; // set channel 3 output ch 1 + st,max-power-correction; // enables power bridge + // correction for THD reduction + // near maximum power output + st,invalid-input-detect-mute; // mute if no valid digital + // audio signal is provided. +}; diff --git a/include/sound/sta350.h b/include/sound/sta350.h new file mode 100644 index 000000000000..3a3298106b22 --- /dev/null +++ b/include/sound/sta350.h @@ -0,0 +1,52 @@ +/* + * Platform data for ST STA350 ASoC codec driver. + * + * Copyright: 2014 Raumfeld GmbH + * Author: Sven Brandau + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __LINUX_SND__STA350_H +#define __LINUX_SND__STA350_H + +#define STA350_OCFG_2CH 0 +#define STA350_OCFG_2_1CH 1 +#define STA350_OCFG_1CH 3 + +#define STA350_OM_CH1 0 +#define STA350_OM_CH2 1 +#define STA350_OM_CH3 2 + +#define STA350_THERMAL_ADJUSTMENT_ENABLE 1 +#define STA350_THERMAL_RECOVERY_ENABLE 2 +#define STA350_FAULT_DETECT_RECOVERY_BYPASS 1 + +#define STA350_FFX_PM_DROP_COMP 0 +#define STA350_FFX_PM_TAPERED_COMP 1 +#define STA350_FFX_PM_FULL_POWER 2 +#define STA350_FFX_PM_VARIABLE_DROP_COMP 3 + + +struct sta350_platform_data { + u8 output_conf; + u8 ch1_output_mapping; + u8 ch2_output_mapping; + u8 ch3_output_mapping; + u8 ffx_power_output_mode; + u8 drop_compensation_ns; + unsigned int thermal_warning_recovery:1; + unsigned int thermal_warning_adjustment:1; + unsigned int fault_detect_recovery:1; + unsigned int oc_warning_adjustment:1; + unsigned int max_power_use_mpcc:1; + unsigned int max_power_correction:1; + unsigned int am_reduction_mode:1; + unsigned int odd_pwm_speed_mode:1; + unsigned int distortion_compensation:1; + unsigned int invalid_input_detect_mute:1; +}; + +#endif /* __LINUX_SND__STA350_H */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..c7b853f520cf 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -80,6 +80,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_SSM2602_SPI if SPI_MASTER select SND_SOC_SSM2602_I2C if I2C select SND_SOC_STA32X if I2C + select SND_SOC_STA350 if I2C select SND_SOC_STA529 if I2C select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TAS5086 if I2C @@ -435,6 +436,10 @@ config SND_SOC_SSM2602_I2C config SND_SOC_STA32X tristate +config SND_SOC_STA350 + tristate "STA350 speaker amplifier" + depends on I2C + config SND_SOC_STA529 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..efdb4d060201 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -74,6 +74,7 @@ snd-soc-ssm2602-objs := ssm2602.o snd-soc-ssm2602-spi-objs := ssm2602-spi.o snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o snd-soc-sta32x-objs := sta32x.o +snd-soc-sta350-objs := sta350.o snd-soc-sta529-objs := sta529.o snd-soc-stac9766-objs := stac9766.o snd-soc-tas5086-objs := tas5086.o @@ -221,6 +222,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o +obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c new file mode 100644 index 000000000000..552e92a6b770 --- /dev/null +++ b/sound/soc/codecs/sta350.c @@ -0,0 +1,1266 @@ +/* + * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system + * + * Copyright: 2014 Raumfeld GmbH + * Author: Sven Brandau + * + * based on code from: + * Raumfeld GmbH + * Johannes Stezenbach + * Wolfson Microelectronics PLC. + * Mark Brown + * Freescale Semiconductor, Inc. + * Timur Tabi + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "sta350.h" + +#define STA350_RATES (SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000) + +#define STA350_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + +/* Power-up register defaults */ +static const struct reg_default sta350_regs[] = { + { 0x0, 0x63 }, + { 0x1, 0x80 }, + { 0x2, 0xdf }, + { 0x3, 0x40 }, + { 0x4, 0xc2 }, + { 0x5, 0x5c }, + { 0x6, 0x00 }, + { 0x7, 0xff }, + { 0x8, 0x60 }, + { 0x9, 0x60 }, + { 0xa, 0x60 }, + { 0xb, 0x00 }, + { 0xc, 0x00 }, + { 0xd, 0x00 }, + { 0xe, 0x00 }, + { 0xf, 0x40 }, + { 0x10, 0x80 }, + { 0x11, 0x77 }, + { 0x12, 0x6a }, + { 0x13, 0x69 }, + { 0x14, 0x6a }, + { 0x15, 0x69 }, + { 0x16, 0x00 }, + { 0x17, 0x00 }, + { 0x18, 0x00 }, + { 0x19, 0x00 }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x00 }, + { 0x1e, 0x00 }, + { 0x1f, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x23, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x27, 0x2a }, + { 0x28, 0xc0 }, + { 0x29, 0xf3 }, + { 0x2a, 0x33 }, + { 0x2b, 0x00 }, + { 0x2c, 0x0c }, + { 0x31, 0x00 }, + { 0x36, 0x00 }, + { 0x37, 0x00 }, + { 0x38, 0x00 }, + { 0x39, 0x01 }, + { 0x3a, 0xee }, + { 0x3b, 0xff }, + { 0x3c, 0x7e }, + { 0x3d, 0xc0 }, + { 0x3e, 0x26 }, + { 0x3f, 0x00 }, + { 0x48, 0x00 }, + { 0x49, 0x00 }, + { 0x4a, 0x00 }, + { 0x4b, 0x04 }, + { 0x4c, 0x00 }, +}; + +static const struct regmap_range sta350_write_regs_range[] = { + regmap_reg_range(STA350_CONFA, STA350_AUTO2), + regmap_reg_range(STA350_C1CFG, STA350_FDRC2), + regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), + regmap_reg_range(STA350_NSHAPE, STA350_MISC2), +}; + +static const struct regmap_range sta350_read_regs_range[] = { + regmap_reg_range(STA350_CONFA, STA350_AUTO2), + regmap_reg_range(STA350_C1CFG, STA350_STATUS), + regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), + regmap_reg_range(STA350_NSHAPE, STA350_MISC2), +}; + +static const struct regmap_range sta350_volatile_regs_range[] = { + regmap_reg_range(STA350_CFADDR2, STA350_CFUD), + regmap_reg_range(STA350_STATUS, STA350_STATUS), +}; + +static const struct regmap_access_table sta350_write_regs = { + .yes_ranges = sta350_write_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_write_regs_range), +}; + +static const struct regmap_access_table sta350_read_regs = { + .yes_ranges = sta350_read_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_read_regs_range), +}; + +static const struct regmap_access_table sta350_volatile_regs = { + .yes_ranges = sta350_volatile_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_volatile_regs_range), +}; + +/* regulator power supply names */ +static const char * const sta350_supply_names[] = { + "vdd-dig", /* digital supply, 3.3V */ + "vdd-pll", /* pll supply, 3.3V */ + "vcc" /* power amp supply, 5V - 26V */ +}; + +/* codec private data */ +struct sta350_priv { + struct regmap *regmap; + struct regulator_bulk_data supplies[ARRAY_SIZE(sta350_supply_names)]; + struct sta350_platform_data *pdata; + + unsigned int mclk; + unsigned int format; + + u32 coef_shadow[STA350_COEF_COUNT]; + int shutdown; + + struct gpio_desc *gpiod_nreset; + struct gpio_desc *gpiod_power_down; + + struct mutex coeff_lock; +}; + +static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1); +static const DECLARE_TLV_DB_SCALE(tone_tlv, -1200, 200, 0); + +static const char * const sta350_drc_ac[] = { + "Anti-Clipping", "Dynamic Range Compression" +}; +static const char * const sta350_auto_gc_mode[] = { + "User", "AC no clipping", "AC limited clipping (10%)", + "DRC nighttime listening mode" +}; +static const char * const sta350_auto_xo_mode[] = { + "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", + "200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", + "340Hz", "360Hz" +}; +static const char * const sta350_binary_output[] = { + "FFX 3-state output - normal operation", "Binary output" +}; +static const char * const sta350_limiter_select[] = { + "Limiter Disabled", "Limiter #1", "Limiter #2" +}; +static const char * const sta350_limiter_attack_rate[] = { + "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024", + "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752", + "0.0645", "0.0564", "0.0501", "0.0451" +}; +static const char * const sta350_limiter_release_rate[] = { + "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299", + "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137", + "0.0134", "0.0117", "0.0110", "0.0104" +}; +static const char * const sta350_noise_shaper_type[] = { + "Third order", "Fourth order" +}; + +static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_attack_tlv, + 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0), + 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_release_tlv, + 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0), + 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0), + 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_attack_tlv, + 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0), + 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0), + 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_release_tlv, + 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), + 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0), + 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0), + 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0), + 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), +); + +static SOC_ENUM_SINGLE_DECL(sta350_drc_ac_enum, + STA350_CONFD, STA350_CONFD_DRC_SHIFT, + sta350_drc_ac); +static SOC_ENUM_SINGLE_DECL(sta350_noise_shaper_enum, + STA350_CONFE, STA350_CONFE_NSBW_SHIFT, + sta350_noise_shaper_type); +static SOC_ENUM_SINGLE_DECL(sta350_auto_gc_enum, + STA350_AUTO1, STA350_AUTO1_AMGC_SHIFT, + sta350_auto_gc_mode); +static SOC_ENUM_SINGLE_DECL(sta350_auto_xo_enum, + STA350_AUTO2, STA350_AUTO2_XO_SHIFT, + sta350_auto_xo_mode); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch1_enum, + STA350_C1CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch2_enum, + STA350_C2CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch3_enum, + STA350_C3CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch1_enum, + STA350_C1CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch2_enum, + STA350_C2CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch3_enum, + STA350_C3CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter1_attack_rate_enum, + STA350_L1AR, STA350_LxA_SHIFT, + sta350_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter2_attack_rate_enum, + STA350_L2AR, STA350_LxA_SHIFT, + sta350_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter1_release_rate_enum, + STA350_L1AR, STA350_LxR_SHIFT, + sta350_limiter_release_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter2_release_rate_enum, + STA350_L2AR, STA350_LxR_SHIFT, + sta350_limiter_release_rate); + +/* + * byte array controls for setting biquad, mixer, scaling coefficients; + * for biquads all five coefficients need to be set in one go, + * mixer and pre/postscale coefs can be set individually; + * each coef is 24bit, the bytes are ordered in the same way + * as given in the STA350 data sheet (big endian; b1, b2, a1, a2, b0) + */ + +static int sta350_coefficient_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int numcoef = kcontrol->private_value >> 16; + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = 3 * numcoef; + return 0; +} + +static int sta350_coefficient_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int numcoef = kcontrol->private_value >> 16; + int index = kcontrol->private_value & 0xffff; + unsigned int cfud, val; + int i, ret = 0; + + mutex_lock(&sta350->coeff_lock); + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + /* + * chip documentation does not say if the bits are self clearing, + * so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + + regmap_write(sta350->regmap, STA350_CFADDR2, index); + if (numcoef == 1) { + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x04); + } else if (numcoef == 5) { + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x08); + } else { + ret = -EINVAL; + goto exit_unlock; + } + + for (i = 0; i < 3 * numcoef; i++) { + regmap_read(sta350->regmap, STA350_B1CF1 + i, &val); + ucontrol->value.bytes.data[i] = val; + } + +exit_unlock: + mutex_unlock(&sta350->coeff_lock); + + return ret; +} + +static int sta350_coefficient_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int numcoef = kcontrol->private_value >> 16; + int index = kcontrol->private_value & 0xffff; + unsigned int cfud; + int i; + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + /* + * chip documentation does not say if the bits are self clearing, + * so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + + regmap_write(sta350->regmap, STA350_CFADDR2, index); + for (i = 0; i < numcoef && (index + i < STA350_COEF_COUNT); i++) + sta350->coef_shadow[index + i] = + (ucontrol->value.bytes.data[3 * i] << 16) + | (ucontrol->value.bytes.data[3 * i + 1] << 8) + | (ucontrol->value.bytes.data[3 * i + 2]); + for (i = 0; i < 3 * numcoef; i++) + regmap_write(sta350->regmap, STA350_B1CF1 + i, + ucontrol->value.bytes.data[i]); + if (numcoef == 1) + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); + else if (numcoef == 5) + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x02); + else + return -EINVAL; + + return 0; +} + +static int sta350_sync_coef_shadow(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int cfud; + int i; + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + + for (i = 0; i < STA350_COEF_COUNT; i++) { + regmap_write(sta350->regmap, STA350_CFADDR2, i); + regmap_write(sta350->regmap, STA350_B1CF1, + (sta350->coef_shadow[i] >> 16) & 0xff); + regmap_write(sta350->regmap, STA350_B1CF2, + (sta350->coef_shadow[i] >> 8) & 0xff); + regmap_write(sta350->regmap, STA350_B1CF3, + (sta350->coef_shadow[i]) & 0xff); + /* + * chip documentation does not say if the bits are + * self-clearing, so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); + } + return 0; +} + +static int sta350_cache_sync(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int mute; + int rc; + + /* mute during register sync */ + regmap_read(sta350->regmap, STA350_CFUD, &mute); + regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE); + sta350_sync_coef_shadow(codec); + rc = regcache_sync(sta350->regmap); + regmap_write(sta350->regmap, STA350_MMUTE, mute); + return rc; +} + +#define SINGLE_COEF(xname, index) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = sta350_coefficient_info, \ + .get = sta350_coefficient_get,\ + .put = sta350_coefficient_put, \ + .private_value = index | (1 << 16) } + +#define BIQUAD_COEFS(xname, index) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = sta350_coefficient_info, \ + .get = sta350_coefficient_get,\ + .put = sta350_coefficient_put, \ + .private_value = index | (5 << 16) } + +static const struct snd_kcontrol_new sta350_snd_controls[] = { +SOC_SINGLE_TLV("Master Volume", STA350_MVOL, 0, 0xff, 1, mvol_tlv), +/* VOL */ +SOC_SINGLE_TLV("Ch1 Volume", STA350_C1VOL, 0, 0xff, 1, chvol_tlv), +SOC_SINGLE_TLV("Ch2 Volume", STA350_C2VOL, 0, 0xff, 1, chvol_tlv), +SOC_SINGLE_TLV("Ch3 Volume", STA350_C3VOL, 0, 0xff, 1, chvol_tlv), +/* CONFD */ +SOC_SINGLE("High Pass Filter Bypass Switch", + STA350_CONFD, STA350_CONFD_HPB_SHIFT, 1, 1), +SOC_SINGLE("De-emphasis Filter Switch", + STA350_CONFD, STA350_CONFD_DEMP_SHIFT, 1, 0), +SOC_SINGLE("DSP Bypass Switch", + STA350_CONFD, STA350_CONFD_DSPB_SHIFT, 1, 0), +SOC_SINGLE("Post-scale Link Switch", + STA350_CONFD, STA350_CONFD_PSL_SHIFT, 1, 0), +SOC_SINGLE("Biquad Coefficient Link Switch", + STA350_CONFD, STA350_CONFD_BQL_SHIFT, 1, 0), +SOC_ENUM("Compressor/Limiter Switch", sta350_drc_ac_enum), +SOC_ENUM("Noise Shaper Bandwidth", sta350_noise_shaper_enum), +SOC_SINGLE("Zero-detect Mute Enable Switch", + STA350_CONFD, STA350_CONFD_ZDE_SHIFT, 1, 0), +SOC_SINGLE("Submix Mode Switch", + STA350_CONFD, STA350_CONFD_SME_SHIFT, 1, 0), +/* CONFE */ +SOC_SINGLE("Zero Cross Switch", STA350_CONFE, STA350_CONFE_ZCE_SHIFT, 1, 0), +SOC_SINGLE("Soft Ramp Switch", STA350_CONFE, STA350_CONFE_SVE_SHIFT, 1, 0), +/* MUTE */ +SOC_SINGLE("Master Switch", STA350_MMUTE, STA350_MMUTE_MMUTE_SHIFT, 1, 1), +SOC_SINGLE("Ch1 Switch", STA350_MMUTE, STA350_MMUTE_C1M_SHIFT, 1, 1), +SOC_SINGLE("Ch2 Switch", STA350_MMUTE, STA350_MMUTE_C2M_SHIFT, 1, 1), +SOC_SINGLE("Ch3 Switch", STA350_MMUTE, STA350_MMUTE_C3M_SHIFT, 1, 1), +/* AUTOx */ +SOC_ENUM("Automode GC", sta350_auto_gc_enum), +SOC_ENUM("Automode XO", sta350_auto_xo_enum), +/* CxCFG */ +SOC_SINGLE("Ch1 Tone Control Bypass Switch", + STA350_C1CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), +SOC_SINGLE("Ch2 Tone Control Bypass Switch", + STA350_C2CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), +SOC_SINGLE("Ch1 EQ Bypass Switch", + STA350_C1CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), +SOC_SINGLE("Ch2 EQ Bypass Switch", + STA350_C2CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), +SOC_SINGLE("Ch1 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_SINGLE("Ch2 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_SINGLE("Ch3 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_ENUM("Ch1 Binary Output Select", sta350_binary_output_ch1_enum), +SOC_ENUM("Ch2 Binary Output Select", sta350_binary_output_ch2_enum), +SOC_ENUM("Ch3 Binary Output Select", sta350_binary_output_ch3_enum), +SOC_ENUM("Ch1 Limiter Select", sta350_limiter_ch1_enum), +SOC_ENUM("Ch2 Limiter Select", sta350_limiter_ch2_enum), +SOC_ENUM("Ch3 Limiter Select", sta350_limiter_ch3_enum), +/* TONE */ +SOC_SINGLE_RANGE_TLV("Bass Tone Control Volume", + STA350_TONE, STA350_TONE_BTC_SHIFT, 1, 13, 0, tone_tlv), +SOC_SINGLE_RANGE_TLV("Treble Tone Control Volume", + STA350_TONE, STA350_TONE_TTC_SHIFT, 1, 13, 0, tone_tlv), +SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta350_limiter1_attack_rate_enum), +SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta350_limiter2_attack_rate_enum), +SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta350_limiter1_release_rate_enum), +SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta350_limiter2_release_rate_enum), + +/* + * depending on mode, the attack/release thresholds have + * two different enum definitions; provide both + */ +SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", + STA350_L1ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_ac_attack_tlv), +SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", + STA350_L2ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_ac_attack_tlv), +SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", + STA350_L1ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_ac_release_tlv), +SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", + STA350_L2ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_ac_release_tlv), +SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", + STA350_L1ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_drc_attack_tlv), +SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", + STA350_L2ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_drc_attack_tlv), +SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", + STA350_L1ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_drc_release_tlv), +SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", + STA350_L2ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_drc_release_tlv), + +BIQUAD_COEFS("Ch1 - Biquad 1", 0), +BIQUAD_COEFS("Ch1 - Biquad 2", 5), +BIQUAD_COEFS("Ch1 - Biquad 3", 10), +BIQUAD_COEFS("Ch1 - Biquad 4", 15), +BIQUAD_COEFS("Ch2 - Biquad 1", 20), +BIQUAD_COEFS("Ch2 - Biquad 2", 25), +BIQUAD_COEFS("Ch2 - Biquad 3", 30), +BIQUAD_COEFS("Ch2 - Biquad 4", 35), +BIQUAD_COEFS("High-pass", 40), +BIQUAD_COEFS("Low-pass", 45), +SINGLE_COEF("Ch1 - Prescale", 50), +SINGLE_COEF("Ch2 - Prescale", 51), +SINGLE_COEF("Ch1 - Postscale", 52), +SINGLE_COEF("Ch2 - Postscale", 53), +SINGLE_COEF("Ch3 - Postscale", 54), +SINGLE_COEF("Thermal warning - Postscale", 55), +SINGLE_COEF("Ch1 - Mix 1", 56), +SINGLE_COEF("Ch1 - Mix 2", 57), +SINGLE_COEF("Ch2 - Mix 1", 58), +SINGLE_COEF("Ch2 - Mix 2", 59), +SINGLE_COEF("Ch3 - Mix 1", 60), +SINGLE_COEF("Ch3 - Mix 2", 61), +}; + +static const struct snd_soc_dapm_widget sta350_dapm_widgets[] = { +SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_OUTPUT("LEFT"), +SND_SOC_DAPM_OUTPUT("RIGHT"), +SND_SOC_DAPM_OUTPUT("SUB"), +}; + +static const struct snd_soc_dapm_route sta350_dapm_routes[] = { + { "LEFT", NULL, "DAC" }, + { "RIGHT", NULL, "DAC" }, + { "SUB", NULL, "DAC" }, + { "DAC", NULL, "Playback" }, +}; + +/* MCLK interpolation ratio per fs */ +static struct { + int fs; + int ir; +} interpolation_ratios[] = { + { 32000, 0 }, + { 44100, 0 }, + { 48000, 0 }, + { 88200, 1 }, + { 96000, 1 }, + { 176400, 2 }, + { 192000, 2 }, +}; + +/* MCLK to fs clock ratios */ +static int mcs_ratio_table[3][6] = { + { 768, 512, 384, 256, 128, 576 }, + { 384, 256, 192, 128, 64, 0 }, + { 192, 128, 96, 64, 32, 0 }, +}; + +/** + * sta350_set_dai_sysclk - configure MCLK + * @codec_dai: the codec DAI + * @clk_id: the clock ID (ignored) + * @freq: the MCLK input frequency + * @dir: the clock direction (ignored) + * + * The value of MCLK is used to determine which sample rates are supported + * by the STA350, based on the mcs_ratio_table. + * + * This function must be called by the machine driver's 'startup' function, + * otherwise the list of supported sample rates will not be available in + * time for ALSA. + */ +static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "mclk=%u\n", freq); + sta350->mclk = freq; + + return 0; +} + +/** + * sta350_set_dai_fmt - configure the codec for the selected audio format + * @codec_dai: the codec DAI + * @fmt: a SND_SOC_DAIFMT_x value indicating the data format + * + * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the + * codec accordingly. + */ +static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int confb = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + sta350->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + confb |= STA350_CONFB_C2IM; + break; + case SND_SOC_DAIFMT_NB_IF: + confb |= STA350_CONFB_C1IM; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(sta350->regmap, STA350_CONFB, + STA350_CONFB_C1IM | STA350_CONFB_C2IM, confb); +} + +/** + * sta350_hw_params - program the STA350 with the given hardware parameters. + * @substream: the audio stream + * @params: the hardware parameters to set + * @dai: the SOC DAI (ignored) + * + * This function programs the hardware with the values provided. + * Specifically, the sample rate and the data format. + */ +static int sta350_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int i, mcs = -EINVAL, ir = -EINVAL; + unsigned int confa, confb; + unsigned int rate, ratio; + int ret; + + if (!sta350->mclk) { + dev_err(codec->dev, + "sta350->mclk is unset. Unable to determine ratio\n"); + return -EIO; + } + + rate = params_rate(params); + ratio = sta350->mclk / rate; + dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio); + + for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) { + if (interpolation_ratios[i].fs == rate) { + ir = interpolation_ratios[i].ir; + break; + } + } + + if (ir < 0) { + dev_err(codec->dev, "Unsupported samplerate: %u\n", rate); + return -EINVAL; + } + + for (i = 0; i < 6; i++) { + if (mcs_ratio_table[ir][i] == ratio) { + mcs = i; + break; + } + } + + if (mcs < 0) { + dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio); + return -EINVAL; + } + + confa = (ir << STA350_CONFA_IR_SHIFT) | + (mcs << STA350_CONFA_MCS_SHIFT); + confb = 0; + + switch (params_width(params)) { + case 24: + dev_dbg(codec->dev, "24bit\n"); + /* fall through */ + case 32: + dev_dbg(codec->dev, "24bit or 32bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x0; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x1; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0x2; + break; + } + + break; + case 20: + dev_dbg(codec->dev, "20bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x4; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x5; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0x6; + break; + } + + break; + case 18: + dev_dbg(codec->dev, "18bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x8; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x9; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0xa; + break; + } + + break; + case 16: + dev_dbg(codec->dev, "16bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x0; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0xd; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0xe; + break; + } + + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(sta350->regmap, STA350_CONFA, + STA350_CONFA_MCS_MASK | STA350_CONFA_IR_MASK, + confa); + if (ret < 0) + return ret; + + ret = regmap_update_bits(sta350->regmap, STA350_CONFB, + STA350_CONFB_SAI_MASK | STA350_CONFB_SAIFB, + confb); + if (ret < 0) + return ret; + + return 0; +} + +static int sta350_startup_sequence(struct sta350_priv *sta350) +{ + if (sta350->gpiod_power_down) + gpiod_set_value(sta350->gpiod_power_down, 1); + + if (sta350->gpiod_nreset) { + gpiod_set_value(sta350->gpiod_nreset, 0); + mdelay(1); + gpiod_set_value(sta350->gpiod_nreset, 1); + mdelay(1); + } + + return 0; +} + +/** + * sta350_set_bias_level - DAPM callback + * @codec: the codec device + * @level: DAPM power level + * + * This is called by ALSA to put the codec into low power mode + * or to wake it up. If the codec is powered off completely + * all registers must be restored after power on. + */ +static int sta350_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int ret; + + dev_dbg(codec->dev, "level = %d\n", level); + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* Full power on */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, + STA350_CONFF_PWDN | STA350_CONFF_EAPD); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable( + ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + sta350_startup_sequence(sta350); + sta350_cache_sync(codec); + } + + /* Power down */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, + 0); + + break; + + case SND_SOC_BIAS_OFF: + /* The chip runs through the power down sequence for us */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, 0); + + /* power down: low */ + if (sta350->gpiod_power_down) + gpiod_set_value(sta350->gpiod_power_down, 0); + + if (sta350->gpiod_nreset) + gpiod_set_value(sta350->gpiod_nreset, 0); + + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), + sta350->supplies); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +static const struct snd_soc_dai_ops sta350_dai_ops = { + .hw_params = sta350_hw_params, + .set_sysclk = sta350_set_dai_sysclk, + .set_fmt = sta350_set_dai_fmt, +}; + +static struct snd_soc_dai_driver sta350_dai = { + .name = "sta350-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = STA350_RATES, + .formats = STA350_FORMATS, + }, + .ops = &sta350_dai_ops, +}; + +#ifdef CONFIG_PM +static int sta350_suspend(struct snd_soc_codec *codec) +{ + sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int sta350_resume(struct snd_soc_codec *codec) +{ + sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define sta350_suspend NULL +#define sta350_resume NULL +#endif + +static int sta350_probe(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + struct sta350_platform_data *pdata = sta350->pdata; + int i, ret = 0, thermal = 0; + + ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + ret = sta350_startup_sequence(sta350); + if (ret < 0) { + dev_err(codec->dev, "Failed to startup device\n"); + return ret; + } + + /* CONFA */ + if (!pdata->thermal_warning_recovery) + thermal |= STA350_CONFA_TWAB; + if (!pdata->thermal_warning_adjustment) + thermal |= STA350_CONFA_TWRB; + if (!pdata->fault_detect_recovery) + thermal |= STA350_CONFA_FDRB; + regmap_update_bits(sta350->regmap, STA350_CONFA, + STA350_CONFA_TWAB | STA350_CONFA_TWRB | + STA350_CONFA_FDRB, + thermal); + + /* CONFC */ + regmap_update_bits(sta350->regmap, STA350_CONFC, + STA350_CONFC_OM_MASK, + pdata->ffx_power_output_mode + << STA350_CONFC_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_CONFC, + STA350_CONFC_CSZ_MASK, + pdata->drop_compensation_ns + << STA350_CONFC_CSZ_SHIFT); + regmap_update_bits(sta350->regmap, + STA350_CONFC, + STA350_CONFC_OCRB, + pdata->oc_warning_adjustment ? + STA350_CONFC_OCRB : 0); + + /* CONFE */ + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_MPCV, + pdata->max_power_use_mpcc ? + STA350_CONFE_MPCV : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_MPC, + pdata->max_power_correction ? + STA350_CONFE_MPC : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_AME, + pdata->am_reduction_mode ? + STA350_CONFE_AME : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_PWMS, + pdata->odd_pwm_speed_mode ? + STA350_CONFE_PWMS : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_DCCV, + pdata->distortion_compensation ? + STA350_CONFE_DCCV : 0); + /* CONFF */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_IDE, + pdata->invalid_input_detect_mute ? + STA350_CONFF_IDE : 0); + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_OCFG_MASK, + pdata->output_conf + << STA350_CONFF_OCFG_SHIFT); + + /* channel to output mapping */ + regmap_update_bits(sta350->regmap, STA350_C1CFG, + STA350_CxCFG_OM_MASK, + pdata->ch1_output_mapping + << STA350_CxCFG_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_C2CFG, + STA350_CxCFG_OM_MASK, + pdata->ch2_output_mapping + << STA350_CxCFG_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_C3CFG, + STA350_CxCFG_OM_MASK, + pdata->ch3_output_mapping + << STA350_CxCFG_OM_SHIFT); + + /* initialize coefficient shadow RAM with reset values */ + for (i = 4; i <= 49; i += 5) + sta350->coef_shadow[i] = 0x400000; + for (i = 50; i <= 54; i++) + sta350->coef_shadow[i] = 0x7fffff; + sta350->coef_shadow[55] = 0x5a9df7; + sta350->coef_shadow[56] = 0x7fffff; + sta350->coef_shadow[59] = 0x7fffff; + sta350->coef_shadow[60] = 0x400000; + sta350->coef_shadow[61] = 0x400000; + + sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); + + return 0; +} + +static int sta350_remove(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + + sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); + + return 0; +} + +static const struct snd_soc_codec_driver sta350_codec = { + .probe = sta350_probe, + .remove = sta350_remove, + .suspend = sta350_suspend, + .resume = sta350_resume, + .set_bias_level = sta350_set_bias_level, + .controls = sta350_snd_controls, + .num_controls = ARRAY_SIZE(sta350_snd_controls), + .dapm_widgets = sta350_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), + .dapm_routes = sta350_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), +}; + +static const struct regmap_config sta350_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = STA350_MISC2, + .reg_defaults = sta350_regs, + .num_reg_defaults = ARRAY_SIZE(sta350_regs), + .cache_type = REGCACHE_RBTREE, + .wr_table = &sta350_write_regs, + .rd_table = &sta350_read_regs, + .volatile_table = &sta350_volatile_regs, +}; + +#ifdef CONFIG_OF +static const struct of_device_id st350_dt_ids[] = { + { .compatible = "st,sta350", }, + { } +}; +MODULE_DEVICE_TABLE(of, st350_dt_ids); + +static const char * const sta350_ffx_modes[] = { + [STA350_FFX_PM_DROP_COMP] = "drop-compensation", + [STA350_FFX_PM_TAPERED_COMP] = "tapered-compensation", + [STA350_FFX_PM_FULL_POWER] = "full-power-mode", + [STA350_FFX_PM_VARIABLE_DROP_COMP] = "variable-drop-compensation", +}; + +static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) +{ + struct device_node *np = dev->of_node; + struct sta350_platform_data *pdata; + const char *ffx_power_mode; + u16 tmp; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + of_property_read_u8(np, "st,output-conf", + &pdata->output_conf); + of_property_read_u8(np, "st,ch1-output-mapping", + &pdata->ch1_output_mapping); + of_property_read_u8(np, "st,ch2-output-mapping", + &pdata->ch2_output_mapping); + of_property_read_u8(np, "st,ch3-output-mapping", + &pdata->ch3_output_mapping); + + if (of_get_property(np, "st,thermal-warning-recovery", NULL)) + pdata->thermal_warning_recovery = 1; + if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) + pdata->thermal_warning_adjustment = 1; + if (of_get_property(np, "st,fault-detect-recovery", NULL)) + pdata->fault_detect_recovery = 1; + + pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP; + if (!of_property_read_string(np, "st,ffx-power-output-mode", + &ffx_power_mode)) { + int i, mode = -EINVAL; + + for (i = 0; i < ARRAY_SIZE(sta350_ffx_modes); i++) + if (!strcasecmp(ffx_power_mode, sta350_ffx_modes[i])) + mode = i; + + if (mode < 0) + dev_warn(dev, "Unsupported ffx output mode: %s\n", + ffx_power_mode); + else + pdata->ffx_power_output_mode = mode; + } + + tmp = 140; + of_property_read_u16(np, "st,drop-compensation-ns", &tmp); + pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; + + if (of_get_property(np, "st,overcurrent-warning-adjustment", NULL)) + pdata->oc_warning_adjustment = 1; + + /* CONFE */ + if (of_get_property(np, "st,max-power-use-mpcc", NULL)) + pdata->max_power_use_mpcc = 1; + + if (of_get_property(np, "st,max-power-correction", NULL)) + pdata->max_power_correction = 1; + + if (of_get_property(np, "st,am-reduction-mode", NULL)) + pdata->am_reduction_mode = 1; + + if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) + pdata->odd_pwm_speed_mode = 1; + + if (of_get_property(np, "st,distortion-compensation", NULL)) + pdata->distortion_compensation = 1; + + /* CONFF */ + if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) + pdata->invalid_input_detect_mute = 1; + + sta350->pdata = pdata; + + return 0; +} +#endif + +static int sta350_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct device *dev = &i2c->dev; + struct sta350_priv *sta350; + int ret, i; + + sta350 = devm_kzalloc(dev, sizeof(struct sta350_priv), GFP_KERNEL); + if (!sta350) + return -ENOMEM; + + mutex_init(&sta350->coeff_lock); + sta350->pdata = dev_get_platdata(dev); + +#ifdef CONFIG_OF + if (dev->of_node) { + ret = sta350_probe_dt(dev, sta350); + if (ret < 0) + return ret; + } +#endif + + /* GPIOs */ + sta350->gpiod_nreset = devm_gpiod_get(dev, "reset"); + if (IS_ERR(sta350->gpiod_nreset)) { + ret = PTR_ERR(sta350->gpiod_nreset); + if (ret != -ENOENT && ret != -ENOSYS) + return ret; + + sta350->gpiod_nreset = NULL; + } else { + gpiod_direction_output(sta350->gpiod_nreset, 0); + } + + sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down"); + if (IS_ERR(sta350->gpiod_power_down)) { + ret = PTR_ERR(sta350->gpiod_power_down); + if (ret != -ENOENT && ret != -ENOSYS) + return ret; + + sta350->gpiod_power_down = NULL; + } else { + gpiod_direction_output(sta350->gpiod_power_down, 0); + } + + /* regulators */ + for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++) + sta350->supplies[i].supply = sta350_supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + sta350->regmap = devm_regmap_init_i2c(i2c, &sta350_regmap); + if (IS_ERR(sta350->regmap)) { + ret = PTR_ERR(sta350->regmap); + dev_err(dev, "Failed to init regmap: %d\n", ret); + return ret; + } + + i2c_set_clientdata(i2c, sta350); + + ret = snd_soc_register_codec(dev, &sta350_codec, &sta350_dai, 1); + if (ret < 0) + dev_err(dev, "Failed to register codec (%d)\n", ret); + + return ret; +} + +static int sta350_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id sta350_i2c_id[] = { + { "sta350", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sta350_i2c_id); + +static struct i2c_driver sta350_i2c_driver = { + .driver = { + .name = "sta350", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(st350_dt_ids), + }, + .probe = sta350_i2c_probe, + .remove = sta350_i2c_remove, + .id_table = sta350_i2c_id, +}; + +module_i2c_driver(sta350_i2c_driver); + +MODULE_DESCRIPTION("ASoC STA350 driver"); +MODULE_AUTHOR("Sven Brandau "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sta350.h b/sound/soc/codecs/sta350.h new file mode 100644 index 000000000000..c3248f0fad2c --- /dev/null +++ b/sound/soc/codecs/sta350.h @@ -0,0 +1,228 @@ +/* + * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system + * + * Copyright: 2011 Raumfeld GmbH + * Author: Sven Brandau + * + * based on code from: + * Raumfeld GmbH + * Johannes Stezenbach + * Wolfson Microelectronics PLC. + * Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASOC_STA_350_H +#define _ASOC_STA_350_H + +/* STA50 register addresses */ + +#define STA350_REGISTER_COUNT 0x4D +#define STA350_COEF_COUNT 62 + +#define STA350_CONFA 0x00 +#define STA350_CONFB 0x01 +#define STA350_CONFC 0x02 +#define STA350_CONFD 0x03 +#define STA350_CONFE 0x04 +#define STA350_CONFF 0x05 +#define STA350_MMUTE 0x06 +#define STA350_MVOL 0x07 +#define STA350_C1VOL 0x08 +#define STA350_C2VOL 0x09 +#define STA350_C3VOL 0x0a +#define STA350_AUTO1 0x0b +#define STA350_AUTO2 0x0c +#define STA350_AUTO3 0x0d +#define STA350_C1CFG 0x0e +#define STA350_C2CFG 0x0f +#define STA350_C3CFG 0x10 +#define STA350_TONE 0x11 +#define STA350_L1AR 0x12 +#define STA350_L1ATRT 0x13 +#define STA350_L2AR 0x14 +#define STA350_L2ATRT 0x15 +#define STA350_CFADDR2 0x16 +#define STA350_B1CF1 0x17 +#define STA350_B1CF2 0x18 +#define STA350_B1CF3 0x19 +#define STA350_B2CF1 0x1a +#define STA350_B2CF2 0x1b +#define STA350_B2CF3 0x1c +#define STA350_A1CF1 0x1d +#define STA350_A1CF2 0x1e +#define STA350_A1CF3 0x1f +#define STA350_A2CF1 0x20 +#define STA350_A2CF2 0x21 +#define STA350_A2CF3 0x22 +#define STA350_B0CF1 0x23 +#define STA350_B0CF2 0x24 +#define STA350_B0CF3 0x25 +#define STA350_CFUD 0x26 +#define STA350_MPCC1 0x27 +#define STA350_MPCC2 0x28 +#define STA350_DCC1 0x29 +#define STA350_DCC2 0x2a +#define STA350_FDRC1 0x2b +#define STA350_FDRC2 0x2c +#define STA350_STATUS 0x2d +/* reserved: 0x2d - 0x30 */ +#define STA350_EQCFG 0x31 +#define STA350_EATH1 0x32 +#define STA350_ERTH1 0x33 +#define STA350_EATH2 0x34 +#define STA350_ERTH2 0x35 +#define STA350_CONFX 0x36 +#define STA350_SVCA 0x37 +#define STA350_SVCB 0x38 +#define STA350_RMS0A 0x39 +#define STA350_RMS0B 0x3a +#define STA350_RMS0C 0x3b +#define STA350_RMS1A 0x3c +#define STA350_RMS1B 0x3d +#define STA350_RMS1C 0x3e +#define STA350_EVOLRES 0x3f +/* reserved: 0x40 - 0x47 */ +#define STA350_NSHAPE 0x48 +#define STA350_CTXB4B1 0x49 +#define STA350_CTXB7B5 0x4a +#define STA350_MISC1 0x4b +#define STA350_MISC2 0x4c + +/* 0x00 CONFA */ +#define STA350_CONFA_MCS_MASK 0x03 +#define STA350_CONFA_MCS_SHIFT 0 +#define STA350_CONFA_IR_MASK 0x18 +#define STA350_CONFA_IR_SHIFT 3 +#define STA350_CONFA_TWRB BIT(5) +#define STA350_CONFA_TWAB BIT(6) +#define STA350_CONFA_FDRB BIT(7) + +/* 0x01 CONFB */ +#define STA350_CONFB_SAI_MASK 0x0f +#define STA350_CONFB_SAI_SHIFT 0 +#define STA350_CONFB_SAIFB BIT(4) +#define STA350_CONFB_DSCKE BIT(5) +#define STA350_CONFB_C1IM BIT(6) +#define STA350_CONFB_C2IM BIT(7) + +/* 0x02 CONFC */ +#define STA350_CONFC_OM_MASK 0x03 +#define STA350_CONFC_OM_SHIFT 0 +#define STA350_CONFC_CSZ_MASK 0x3c +#define STA350_CONFC_CSZ_SHIFT 2 +#define STA350_CONFC_OCRB BIT(7) + +/* 0x03 CONFD */ +#define STA350_CONFD_HPB_SHIFT 0 +#define STA350_CONFD_DEMP_SHIFT 1 +#define STA350_CONFD_DSPB_SHIFT 2 +#define STA350_CONFD_PSL_SHIFT 3 +#define STA350_CONFD_BQL_SHIFT 4 +#define STA350_CONFD_DRC_SHIFT 5 +#define STA350_CONFD_ZDE_SHIFT 6 +#define STA350_CONFD_SME_SHIFT 7 + +/* 0x04 CONFE */ +#define STA350_CONFE_MPCV BIT(0) +#define STA350_CONFE_MPCV_SHIFT 0 +#define STA350_CONFE_MPC BIT(1) +#define STA350_CONFE_MPC_SHIFT 1 +#define STA350_CONFE_NSBW BIT(2) +#define STA350_CONFE_NSBW_SHIFT 2 +#define STA350_CONFE_AME BIT(3) +#define STA350_CONFE_AME_SHIFT 3 +#define STA350_CONFE_PWMS BIT(4) +#define STA350_CONFE_PWMS_SHIFT 4 +#define STA350_CONFE_DCCV BIT(5) +#define STA350_CONFE_DCCV_SHIFT 5 +#define STA350_CONFE_ZCE BIT(6) +#define STA350_CONFE_ZCE_SHIFT 6 +#define STA350_CONFE_SVE BIT(7) +#define STA350_CONFE_SVE_SHIFT 7 + +/* 0x05 CONFF */ +#define STA350_CONFF_OCFG_MASK 0x03 +#define STA350_CONFF_OCFG_SHIFT 0 +#define STA350_CONFF_IDE BIT(2) +#define STA350_CONFF_BCLE BIT(3) +#define STA350_CONFF_LDTE BIT(4) +#define STA350_CONFF_ECLE BIT(5) +#define STA350_CONFF_PWDN BIT(6) +#define STA350_CONFF_EAPD BIT(7) + +/* 0x06 MMUTE */ +#define STA350_MMUTE_MMUTE 0x01 +#define STA350_MMUTE_MMUTE_SHIFT 0 +#define STA350_MMUTE_C1M 0x02 +#define STA350_MMUTE_C1M_SHIFT 1 +#define STA350_MMUTE_C2M 0x04 +#define STA350_MMUTE_C2M_SHIFT 2 +#define STA350_MMUTE_C3M 0x08 +#define STA350_MMUTE_C3M_SHIFT 3 +#define STA350_MMUTE_LOC_MASK 0xC0 +#define STA350_MMUTE_LOC_SHIFT 6 + +/* 0x0b AUTO1 */ +#define STA350_AUTO1_AMGC_MASK 0x30 +#define STA350_AUTO1_AMGC_SHIFT 4 + +/* 0x0c AUTO2 */ +#define STA350_AUTO2_AMAME 0x01 +#define STA350_AUTO2_AMAM_MASK 0x0e +#define STA350_AUTO2_AMAM_SHIFT 1 +#define STA350_AUTO2_XO_MASK 0xf0 +#define STA350_AUTO2_XO_SHIFT 4 + +/* 0x0d AUTO3 */ +#define STA350_AUTO3_PEQ_MASK 0x1f +#define STA350_AUTO3_PEQ_SHIFT 0 + +/* 0x0e 0x0f 0x10 CxCFG */ +#define STA350_CxCFG_TCB_SHIFT 0 +#define STA350_CxCFG_EQBP_SHIFT 1 +#define STA350_CxCFG_VBP_SHIFT 2 +#define STA350_CxCFG_BO_SHIFT 3 +#define STA350_CxCFG_LS_SHIFT 4 +#define STA350_CxCFG_OM_MASK 0xc0 +#define STA350_CxCFG_OM_SHIFT 6 + +/* 0x11 TONE */ +#define STA350_TONE_BTC_SHIFT 0 +#define STA350_TONE_TTC_SHIFT 4 + +/* 0x12 0x13 0x14 0x15 limiter attack/release */ +#define STA350_LxA_SHIFT 0 +#define STA350_LxR_SHIFT 4 + +/* 0x26 CFUD */ +#define STA350_CFUD_W1 0x01 +#define STA350_CFUD_WA 0x02 +#define STA350_CFUD_R1 0x04 +#define STA350_CFUD_RA 0x08 + + +/* biquad filter coefficient table offsets */ +#define STA350_C1_BQ_BASE 0 +#define STA350_C2_BQ_BASE 20 +#define STA350_CH_BQ_NUM 4 +#define STA350_BQ_NUM_COEF 5 +#define STA350_XO_HP_BQ_BASE 40 +#define STA350_XO_LP_BQ_BASE 45 +#define STA350_C1_PRESCALE 50 +#define STA350_C2_PRESCALE 51 +#define STA350_C1_POSTSCALE 52 +#define STA350_C2_POSTSCALE 53 +#define STA350_C3_POSTSCALE 54 +#define STA350_TW_POSTSCALE 55 +#define STA350_C1_MIX1 56 +#define STA350_C1_MIX2 57 +#define STA350_C2_MIX1 58 +#define STA350_C2_MIX2 59 +#define STA350_C3_MIX1 60 +#define STA350_C3_MIX2 61 + +#endif /* _ASOC_STA_350_H */ From 151eea367c720db8a0768caf47894c32991aa02a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 14 Apr 2014 18:01:47 +0200 Subject: [PATCH 0167/1034] pata_arasan_cf: fix ata_host_activate() failure handling Add missing cf_exit() and clk_put() calls to ata_host_activate() failure path. Cc: Viresh Kumar Cc: Shiraz Hashim Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Viresh Kumar Signed-off-by: Tejun Heo --- drivers/ata/pata_arasan_cf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 6fac524c2f50..4edb1a81f63f 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev) cf_card_detect(acdev, 0); - return ata_host_activate(host, acdev->irq, irq_handler, 0, - &arasan_cf_sht); + ret = ata_host_activate(host, acdev->irq, irq_handler, 0, + &arasan_cf_sht); + if (!ret) + return 0; + cf_exit(acdev); free_clk: clk_put(acdev->clk); return ret; From 0040e606e35a0db80fc3fac04ccc7c7176a8e2b1 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Sat, 12 Apr 2014 13:33:13 +0200 Subject: [PATCH 0168/1034] btrfs: fix use-after-free in mount_subvol() Pointer 'newargs' is used after the memory that it points to has already been freed. Picked up by Coverity - CID 1201425. Fixes: 0723a0473f ("btrfs: allow mounting btrfs subvolumes with different ro/rw options") Signed-off-by: Christoph Jaeger Signed-off-by: Chris Mason --- fs/btrfs/super.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 994c40955315..53bc3733d483 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1186,7 +1186,6 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, return ERR_PTR(-ENOMEM); mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, newargs); - kfree(newargs); if (PTR_RET(mnt) == -EBUSY) { if (flags & MS_RDONLY) { @@ -1196,17 +1195,22 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, int r; mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY, device_name, newargs); - if (IS_ERR(mnt)) + if (IS_ERR(mnt)) { + kfree(newargs); return ERR_CAST(mnt); + } r = btrfs_remount(mnt->mnt_sb, &flags, NULL); if (r < 0) { /* FIXME: release vfsmount mnt ??*/ + kfree(newargs); return ERR_PTR(r); } } } + kfree(newargs); + if (IS_ERR(mnt)) return ERR_CAST(mnt); From ccffbd27af95700f6e46f5300fcc96c0cda9f178 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:08 +0530 Subject: [PATCH 0169/1034] ASoC: pcm512x: Use CONFIG_PM_RUNTIME macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following compilation warnings: sound/soc/codecs/pcm512x.c:520:12: warning: ‘pcm512x_suspend’ defined but not used [-Wunused-function] sound/soc/codecs/pcm512x.c:545:12: warning: ‘pcm512x_resume’ defined but not used [-Wunused-function] Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/pcm512x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 4b4c0c7bb918..51124202f765 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -517,6 +517,7 @@ void pcm512x_remove(struct device *dev) } EXPORT_SYMBOL_GPL(pcm512x_remove); +#ifdef CONFIG_PM_RUNTIME static int pcm512x_suspend(struct device *dev) { struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); @@ -578,6 +579,7 @@ static int pcm512x_resume(struct device *dev) return 0; } +#endif const struct dev_pm_ops pcm512x_pm_ops = { SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) From a6b34312b027833de87c31e63a5d06b07186bacf Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:09 +0530 Subject: [PATCH 0170/1034] ASoC: hdmi: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 9cb1c7d3e1dc..1087fd5f9917 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #define DRV_NAME "hdmi-audio-codec" From 6e1f29d4ef1c13ab87fe785fe6e1213d57232a31 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:10 +0530 Subject: [PATCH 0171/1034] ASoC: max98090: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..4959e762f88a 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include From affb74ad299631666e5bf1f455e3baa7035ea58f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:11 +0530 Subject: [PATCH 0172/1034] ASoC: rt5640: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..635363cb73e9 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include From 0faabc4f4c31deb73077e9f77989406e2fc49c77 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:12 +0530 Subject: [PATCH 0173/1034] ASoC: tlv320aic23: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23-i2c.c | 1 + sound/soc/codecs/tlv320aic31xx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c index b73c94ebcc2a..f13701995482 100644 --- a/sound/soc/codecs/tlv320aic23-i2c.c +++ b/sound/soc/codecs/tlv320aic23-i2c.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index fa158cfe9b32..b93d500e960b 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include From ee5e4534f7b39aaf1256d3de14f412489d5879df Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:13 +0530 Subject: [PATCH 0174/1034] ASoC: tpa6130a2: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/tpa6130a2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index b27c396037d4..8fc5a647453b 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "tpa6130a2.h" From 12023a9af8f6602e09d9276d3476f6861ca0f127 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:25 +0100 Subject: [PATCH 0175/1034] ASoC: core: Add helpers for codec and codec_dai search Add dedicated helpers for codec and codec_dai search in preparation for DAI-multicodec. It will help reducing the extra indentation that will be introduced by the iteration over multiple codecs. Previous implementation unnecessarily kept searching for a matching codec in the remaining register codecs even if it was already found. Fix that by returning in case of matching. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 79 ++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..674da7049db4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -854,14 +854,47 @@ EXPORT_SYMBOL_GPL(snd_soc_resume); static const struct snd_soc_dai_ops null_dai_ops = { }; +static struct snd_soc_codec *soc_find_codec(const struct device_node *codec_of_node, + const char *codec_name) +{ + struct snd_soc_codec *codec; + + list_for_each_entry(codec, &codec_list, list) { + if (codec_of_node) { + if (codec->dev->of_node != codec_of_node) + continue; + } else { + if (strcmp(codec->name, codec_name)) + continue; + } + + return codec; + } + + return NULL; +} + +static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, + const char *codec_dai_name) +{ + struct snd_soc_dai *codec_dai; + + list_for_each_entry(codec_dai, &codec->component.dai_list, list) { + if (!strcmp(codec_dai->name, codec_dai_name)) { + return codec_dai; + } + } + + return NULL; +} + static int soc_bind_dai_link(struct snd_soc_card *card, int num) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; struct snd_soc_component *component; - struct snd_soc_codec *codec; struct snd_soc_platform *platform; - struct snd_soc_dai *codec_dai, *cpu_dai; + struct snd_soc_dai *cpu_dai; const char *platform_name; dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); @@ -889,42 +922,24 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) return -EPROBE_DEFER; } - /* Find CODEC from registered CODECs */ - list_for_each_entry(codec, &codec_list, list) { - if (dai_link->codec_of_node) { - if (codec->dev->of_node != dai_link->codec_of_node) - continue; - } else { - if (strcmp(codec->name, dai_link->codec_name)) - continue; - } - - rtd->codec = codec; - - /* - * CODEC found, so find CODEC DAI from registered DAIs from - * this CODEC - */ - list_for_each_entry(codec_dai, &codec->component.dai_list, list) { - if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) { - rtd->codec_dai = codec_dai; - break; - } - } - - if (!rtd->codec_dai) { - dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", - dai_link->codec_dai_name); - return -EPROBE_DEFER; - } - } - + /* Find CODEC from registered list */ + rtd->codec = soc_find_codec(dai_link->codec_of_node, + dai_link->codec_name); if (!rtd->codec) { dev_err(card->dev, "ASoC: CODEC %s not registered\n", dai_link->codec_name); return -EPROBE_DEFER; } + /* Find CODEC DAI from registered list */ + rtd->codec_dai = soc_find_codec_dai(rtd->codec, + dai_link->codec_dai_name); + if (!rtd->codec_dai) { + dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", + dai_link->codec_dai_name); + return -EPROBE_DEFER; + } + /* if there's no platform we match on the empty platform */ platform_name = dai_link->platform_name; if (!platform_name && !dai_link->platform_of_node) From b0aa88af23155b18efb8c18ace963fa75778561a Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:26 +0100 Subject: [PATCH 0176/1034] ASoC: core: Add helpers for codec DAI probe & remove Add helper functions for codec DAI probe and remove in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 74 ++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 674da7049db4..1e4945d614a4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1010,6 +1010,24 @@ static void soc_remove_codec(struct snd_soc_codec *codec) module_put(codec->dev->driver->owner); } +static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) +{ + int err; + + if (codec_dai && codec_dai->probed && + codec_dai->driver->remove_order == order) { + if (codec_dai->driver->remove) { + err = codec_dai->driver->remove(codec_dai); + if (err < 0) + dev_err(codec_dai->dev, + "ASoC: failed to remove %s: %d\n", + codec_dai->name, err); + } + codec_dai->probed = 0; + list_del(&codec_dai->card_list); + } +} + static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; @@ -1025,18 +1043,7 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) } /* remove the CODEC DAI */ - if (codec_dai && codec_dai->probed && - codec_dai->driver->remove_order == order) { - if (codec_dai->driver->remove) { - err = codec_dai->driver->remove(codec_dai); - if (err < 0) - dev_err(codec_dai->dev, - "ASoC: failed to remove %s: %d\n", - codec_dai->name, err); - } - codec_dai->probed = 0; - list_del(&codec_dai->card_list); - } + soc_remove_codec_dai(codec_dai, order); /* remove the cpu_dai */ if (cpu_dai && cpu_dai->probed && @@ -1381,6 +1388,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, return 0; } +static int soc_probe_codec_dai(struct snd_soc_card *card, + struct snd_soc_dai *codec_dai, + int order) +{ + int ret; + + if (!codec_dai->probed && codec_dai->driver->probe_order == order) { + if (codec_dai->driver->probe) { + ret = codec_dai->driver->probe(codec_dai); + if (ret < 0) { + dev_err(codec_dai->dev, + "ASoC: failed to probe CODEC DAI %s: %d\n", + codec_dai->name, ret); + return ret; + } + } + + /* mark codec_dai as probed and add to card dai list */ + codec_dai->probed = 1; + list_add(&codec_dai->card_list, &card->dai_dev_list); + } + + return 0; +} + static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; @@ -1430,21 +1462,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } /* probe the CODEC DAI */ - if (!codec_dai->probed && codec_dai->driver->probe_order == order) { - if (codec_dai->driver->probe) { - ret = codec_dai->driver->probe(codec_dai); - if (ret < 0) { - dev_err(codec_dai->dev, - "ASoC: failed to probe CODEC DAI %s: %d\n", - codec_dai->name, ret); - return ret; - } - } - - /* mark codec_dai as probed and add to card dai list */ - codec_dai->probed = 1; - list_add(&codec_dai->card_list, &card->dai_dev_list); - } + ret = soc_probe_codec_dai(card, codec_dai, order); + if (ret) + return ret; /* complete DAI probe during last probe */ if (order != SND_SOC_COMP_ORDER_LAST) From 2436a723f3e1fbca517c9318efe9af5ecf7cbcbb Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:27 +0100 Subject: [PATCH 0177/1034] ASoC: core: Add helper for DAI widgets linking Add a helper for DAI widgets linking in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 64 +++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1e4945d614a4..4c0f7dccbd83 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1413,6 +1413,42 @@ static int soc_probe_codec_dai(struct snd_soc_card *card, return 0; } +static int soc_link_dai_widgets(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link, + struct snd_soc_dai *cpu_dai, + struct snd_soc_dai *codec_dai) +{ + struct snd_soc_dapm_widget *play_w, *capture_w; + int ret; + + /* link the DAI widgets */ + play_w = codec_dai->playback_widget; + capture_w = cpu_dai->capture_widget; + if (play_w && capture_w) { + ret = snd_soc_dapm_new_pcm(card, dai_link->params, + capture_w, play_w); + if (ret != 0) { + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", + play_w->name, capture_w->name, ret); + return ret; + } + } + + play_w = cpu_dai->playback_widget; + capture_w = codec_dai->capture_widget; + if (play_w && capture_w) { + ret = snd_soc_dapm_new_pcm(card, dai_link->params, + capture_w, play_w); + if (ret != 0) { + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", + play_w->name, capture_w->name, ret); + return ret; + } + } + + return 0; +} + static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; @@ -1421,7 +1457,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dapm_widget *play_w, *capture_w; int ret; dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", @@ -1502,29 +1537,10 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) codec2codec_close_delayed_work); /* link the DAI widgets */ - play_w = codec_dai->playback_widget; - capture_w = cpu_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } - - play_w = cpu_dai->playback_widget; - capture_w = codec_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } + ret = soc_link_dai_widgets(card, dai_link, + cpu_dai, codec_dai); + if (ret) + return ret; } } From 02c9c7b91c2831b7f4e43c9931007e46f856b659 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:28 +0100 Subject: [PATCH 0178/1034] ASoC: core: Add function for ac97 codec registration Add codec registration specific function in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c0f7dccbd83..42c5835ba92f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1552,14 +1552,15 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } #ifdef CONFIG_SND_SOC_AC97_BUS -static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +static int soc_register_ac97_codec(struct snd_soc_codec *codec, + struct snd_soc_dai *codec_dai) { int ret; /* Only instantiate AC97 if not already done by the adaptor * for the generic AC97 subsystem. */ - if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) { + if (codec_dai->driver->ac97_control && !codec->ac97_registered) { /* * It is possible that the AC97 device is already registered to * the device subsystem. This happens when the device is created @@ -1568,28 +1569,38 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) * * In those cases we don't try to register the device again. */ - if (!rtd->codec->ac97_created) + if (!codec->ac97_created) return 0; - ret = soc_ac97_dev_register(rtd->codec); + ret = soc_ac97_dev_register(codec); if (ret < 0) { - dev_err(rtd->codec->dev, + dev_err(codec->dev, "ASoC: AC97 device register failed: %d\n", ret); return ret; } - rtd->codec->ac97_registered = 1; + codec->ac97_registered = 1; } return 0; } -static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec) +static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + return soc_register_ac97_codec(rtd->codec, rtd->codec_dai); +} + +static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) { if (codec->ac97_registered) { soc_ac97_dev_unregister(codec); codec->ac97_registered = 0; } } + +static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + soc_unregister_ac97_codec(rtd->codec); +} #endif static int soc_check_aux_dev(struct snd_soc_card *card, int num) @@ -1888,7 +1899,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) dev_err(card->dev, "ASoC: failed to register AC97: %d\n", ret); while (--i >= 0) - soc_unregister_ac97_dai_link(card->rtd[i].codec); + soc_unregister_ac97_dai_link(&card->rtd[i]); goto probe_aux_dev_err; } } @@ -2324,7 +2335,7 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) { mutex_lock(&codec->mutex); #ifdef CONFIG_SND_SOC_AC97_BUS - soc_unregister_ac97_dai_link(codec); + soc_unregister_ac97_codec(codec); #endif kfree(codec->ac97->bus); kfree(codec->ac97); From 84bd187996777924b70fe6fb39ccaa34e0b57565 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:56 +0200 Subject: [PATCH 0179/1034] ASoC: adau1373: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1373.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 877f5737bb6b..1ff7d4d027e9 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -519,8 +519,7 @@ static const struct snd_kcontrol_new adau1373_controls[] = { SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), - SOC_VALUE_ENUM("Bass Clip Level Threshold", - adau1373_bass_clip_level_enum), + SOC_ENUM("Bass Clip Level Threshold", adau1373_bass_clip_level_enum), SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, @@ -580,7 +579,7 @@ static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum, adau1373_decimator_text); static const struct snd_kcontrol_new adau1373_decimator_mux = - SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); + SOC_DAPM_ENUM("Decimator Mux", adau1373_decimator_enum); static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), @@ -694,7 +693,7 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), - SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, &adau1373_decimator_mux), SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), From 48fa3636340f78d10352dd333e79946de0a96fe6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:57 +0200 Subject: [PATCH 0180/1034] ASoC: adav80x: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adav80x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 5062e34ee8dc..4d41bbc611e0 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -172,14 +172,14 @@ static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3); static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3); static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum); + SOC_DAPM_ENUM("Route", adav80x_aux_capture_enum); static const struct snd_kcontrol_new adav80x_capture_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum); + SOC_DAPM_ENUM("Route", adav80x_capture_enum); static const struct snd_kcontrol_new adav80x_dac_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum); + SOC_DAPM_ENUM("Route", adav80x_dac_enum); #define ADAV80X_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1), From 355e3a08485249868d892c82e9250c0f6e4d0ceb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:58 +0200 Subject: [PATCH 0181/1034] ASoC: arizona: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 16df0f913353..05ae17f5bca3 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -107,7 +107,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; #define ARIZONA_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define ARIZONA_MUX_ENUMS(name, base_reg) \ static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ @@ -128,7 +128,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) #define ARIZONA_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define ARIZONA_MUX_WIDGETS(name, name_str) \ ARIZONA_MUX(name_str " Input", &name##_mux) From aae1137b998a1a4508a2f2b27604351a5ced2427 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:59 +0200 Subject: [PATCH 0182/1034] ASoC: max98090: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..1fd31efa6664 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -875,7 +875,7 @@ static const char *dmic_mux_text[] = { "ADC", "DMIC" }; static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); static const struct snd_kcontrol_new max98090_dmic_mux = - SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); + SOC_DAPM_ENUM("DMIC Mux", dmic_mux_enum); static const char *max98090_micpre_text[] = { "Off", "On" }; @@ -1175,8 +1175,7 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = { SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM, 0, 0, &max98090_mic2_mux), - SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM, - 0, 0, &max98090_dmic_mux), + SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &max98090_dmic_mux), SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event, From 36bc38a7c1c6869a71739c4f9bf1c16e8168ae88 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:00 +0200 Subject: [PATCH 0183/1034] ASoC: mc13783: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2c59b1fb69dc..ed5c5a41169b 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -409,7 +409,7 @@ static const char * const adcl_enum_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); static const struct snd_kcontrol_new left_input_mux = - SOC_DAPM_ENUM_VIRT("Route", adcl_enum); + SOC_DAPM_ENUM("Route", adcl_enum); static const char * const adcr_enum_text[] = { "MC1R", "MC2", "RXINR", "TXIN", @@ -418,7 +418,7 @@ static const char * const adcr_enum_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); static const struct snd_kcontrol_new right_input_mux = - SOC_DAPM_ENUM_VIRT("Route", adcr_enum); + SOC_DAPM_ENUM("Route", adcr_enum); static const struct snd_kcontrol_new samp_ctl = SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); @@ -478,9 +478,9 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl), SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl), - SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, &left_input_mux), - SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, &right_input_mux), SND_SOC_DAPM_MUX("Speaker Amp Source MUX", SND_SOC_NOPM, 0, 0, From 54581be7da3d50aab8322fcfeff14c1aa1dafa86 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:01 +0200 Subject: [PATCH 0184/1034] ASoC: pcm512x: Replace usage deprecated SOC_VALUE_ENUM macro SOC_VALUE_ENUM is deprecated and merely an alias for SOC_ENUM. Replace the deprecated macro so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/pcm512x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 4b4c0c7bb918..381d22ce6f76 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -269,7 +269,7 @@ SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, PCM512x_RQMR_SHIFT, 1, 1), SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), -SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program), +SOC_ENUM("DSP Program", pcm512x_dsp_program), SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), From 712fb1c27dce4e3fe9338f27ed0f8684fe9d5597 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:02 +0200 Subject: [PATCH 0185/1034] ASoC: rt5640: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..1b452e3b449a 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -824,7 +824,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); static const struct snd_kcontrol_new rt5640_dac_l2_mux = - SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); + SOC_DAPM_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); static const char * const rt5640_dac_r2_src[] = { "IF2", @@ -859,7 +859,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum, rt5640_dai_iis_map_values); static const struct snd_kcontrol_new rt5640_dai_mux = - SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); + SOC_DAPM_ENUM("DAI select", rt5640_dai_iis_map_enum); /* SDI select */ static const char * const rt5640_sdi_sel[] = { From 7eb364ab196d522cdde744010c4e02c2fe62f6fc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:03 +0200 Subject: [PATCH 0186/1034] ASoC: wm2200: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 2e721e06671b..cdea9d9c1631 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1083,7 +1083,7 @@ static int wm2200_mixer_values[] = { #define WM2200_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define WM2200_MIXER_ENUMS(name, base_reg) \ static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ @@ -1207,7 +1207,7 @@ WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); #define WM2200_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define WM2200_MIXER_WIDGETS(name, name_str) \ WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ From cda8866952f209d5e9de077c9ea7cb20a22e41ea Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:04 +0200 Subject: [PATCH 0187/1034] ASoC: wm5100: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index eca983fad891..91a9ea2a2056 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -390,7 +390,7 @@ static int wm5100_mixer_values[] = { #define WM5100_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define WM5100_MIXER_ENUMS(name, base_reg) \ static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ @@ -448,7 +448,7 @@ WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE); WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE); #define WM5100_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define WM5100_MIXER_WIDGETS(name, name_str) \ WM5100_MUX(name_str " Input 1", &name##_in1_mux), \ From 6b2cab02a39d2d1badf93c44e989ffcb9c3c1363 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:05 +0200 Subject: [PATCH 0188/1034] ASoC: wm5102: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index dcf1d12cfef8..12d244b8f281 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -970,7 +970,7 @@ static const struct soc_enum wm5102_aec_loopback = wm5102_aec_loopback_values); static const struct snd_kcontrol_new wm5102_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm5102_aec_loopback); static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -1204,7 +1204,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5102_aec_loopback_mux), From 696d3affa012a439f9e6be1e60cc68ce06d736d1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:06 +0200 Subject: [PATCH 0189/1034] ASoC: wm5110: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..32e503211eec 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -324,13 +324,13 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), -SOC_VALUE_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), -SOC_VALUE_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), -SOC_VALUE_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), -SOC_VALUE_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), -SOC_VALUE_ENUM("ASRC RATE 1", arizona_asrc_rate1), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), +SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), +SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), +SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), +SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1), ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), @@ -592,7 +592,7 @@ static const struct soc_enum wm5110_aec_loopback = wm5110_aec_loopback_values); static const struct snd_kcontrol_new wm5110_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback); static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -774,7 +774,7 @@ SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3, SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3, ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5110_aec_loopback_mux), From fb7d79e56f6b0b7ce2d0ae3366d6a0e59145e37d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:07 +0200 Subject: [PATCH 0190/1034] ASoC: wm8988: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8988.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 3a1ae4f5164d..d3fea46d58e8 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -268,7 +268,7 @@ static const struct soc_enum wm8988_lline_enum = wm8988_line_texts, wm8988_line_values); static const struct snd_kcontrol_new wm8988_left_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + SOC_DAPM_ENUM("Route", wm8988_lline_enum); static const struct soc_enum wm8988_rline_enum = SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, @@ -276,7 +276,7 @@ static const struct soc_enum wm8988_rline_enum = wm8988_line_texts, wm8988_line_values); static const struct snd_kcontrol_new wm8988_right_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + SOC_DAPM_ENUM("Route", wm8988_lline_enum); /* Left Mixer */ static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { @@ -304,7 +304,7 @@ static const struct soc_enum wm8988_lpga_enum = wm8988_pga_sel, wm8988_pga_val); static const struct snd_kcontrol_new wm8988_left_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum); + SOC_DAPM_ENUM("Route", wm8988_lpga_enum); /* Right PGA Mux */ static const struct soc_enum wm8988_rpga_enum = @@ -313,7 +313,7 @@ static const struct soc_enum wm8988_rpga_enum = wm8988_pga_sel, wm8988_pga_val); static const struct snd_kcontrol_new wm8988_right_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum); + SOC_DAPM_ENUM("Route", wm8988_rpga_enum); /* Differential Mux */ static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; From 0a822c1e3bfd00e7a9a5d81ac5887defdd5d4e64 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:08 +0200 Subject: [PATCH 0191/1034] ASoC: wm5102: Replace usage deprecated SOC_VALUE_ENUM macro SOC_VALUE_ENUM is deprecated and merely an alias for SOC_EMUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 12d244b8f281..cbe52861b19b 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -764,8 +764,8 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -814,9 +814,9 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), -SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), -SOC_VALUE_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), +SOC_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), +SOC_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), +SOC_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE, ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0), From 37d203055e3516e891fb23a40d61a54b65a60d81 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:09 +0200 Subject: [PATCH 0192/1034] ASoC: wm8994: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX, SND_SOC_DAPM_VIRT_MUX_E and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX, SND_SOC_DAPM_MUX_E and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..309c97d89dbb 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1347,10 +1347,10 @@ static const char *adc_mux_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); static const struct snd_kcontrol_new adcl_mux = - SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); + SOC_DAPM_ENUM("ADCL Mux", adc_enum); static const struct snd_kcontrol_new adcr_mux = - SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); + SOC_DAPM_ENUM("ADCR Mux", adc_enum); static const struct snd_kcontrol_new left_speaker_mixer[] = { SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0), @@ -1651,15 +1651,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), }; static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { -SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, +SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, adc_mux_ev, SND_SOC_DAPM_PRE_PMU), -SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, +SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, adc_mux_ev, SND_SOC_DAPM_PRE_PMU), }; static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { -SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), }; static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { From b8eecc19708dcf36b30058a1e86206480c09efc4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:10 +0200 Subject: [PATCH 0193/1034] ASoC: wm8995: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8995.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index d3152cf5bd56..863a2c38bcb5 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -885,10 +885,10 @@ static const char *adc_mux_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); static const struct snd_kcontrol_new adcl_mux = - SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); + SOC_DAPM_ENUM("ADCL Mux", adc_enum); static const struct snd_kcontrol_new adcr_mux = - SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); + SOC_DAPM_ENUM("ADCR Mux", adc_enum); static const char *spk_src_text[] = { "DAC1L", "DAC1R", "DAC2L", "DAC2R" @@ -948,10 +948,8 @@ static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 0, WM8995_POWER_MANAGEMENT_3, 10, 0), - SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, - &adcl_mux), - SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, - &adcr_mux), + SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, &adcl_mux), + SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0), SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0), From e13dd8ce39a89c7a7d8ec025b266337b42eeaafc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:11 +0200 Subject: [PATCH 0194/1034] ASoC: wm8997: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 004186b6bd48..e45bbc0f15b2 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -245,8 +245,8 @@ SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_VALUE("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_VALUE("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -286,8 +286,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), -SOC_VALUE_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), +SOC_VALUE("HPOUT1 OSR", wm8997_hpout_osr[0]), +SOC_VALUE("EPOUT OSR", wm8997_hpout_osr[1]), SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), @@ -405,7 +405,7 @@ static const struct soc_enum wm8997_aec_loopback = wm8997_aec_loopback_values); static const struct snd_kcontrol_new wm8997_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm8997_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm8997_aec_loopback); static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -604,7 +604,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE, ARIZONA_SLIMRX8_ENA_SHIFT, 0), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm8997_aec_loopback_mux), From 785b3c4e0951252cdbc0cd902292bf5c9f08897a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:12 +0200 Subject: [PATCH 0195/1034] ASoC: Remove deprecated ENUM/MUX macros Since there are no users left, we can remove the deprecated ENUM and MUX macros which are just alias for other macros. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 12 ------------ include/sound/soc.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index ef78f562f4a8..5ec03b5e2054 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -107,10 +107,6 @@ struct device; { .id = snd_soc_dapm_mux, .name = wname, \ SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ .kcontrol_news = wcontrols, .num_kcontrols = 1} -#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ - SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) -#define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ - SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ #define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ @@ -166,10 +162,6 @@ struct device; SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ .kcontrol_news = wcontrols, .num_kcontrols = 1, \ .event = wevent, .event_flags = wflags} -#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ - wevent, wflags) \ - SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, wevent, \ - wflags) /* additional sequencing control within an event type */ #define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \ @@ -305,16 +297,12 @@ struct device; .get = snd_soc_dapm_get_enum_double, \ .put = snd_soc_dapm_put_enum_double, \ .private_value = (unsigned long)&xenum } -#define SOC_DAPM_ENUM_VIRT(xname, xenum) \ - SOC_DAPM_ENUM(xname, xenum) #define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_enum_double, \ .get = xget, \ .put = xput, \ .private_value = (unsigned long)&xenum } -#define SOC_DAPM_VALUE_ENUM(xname, xenum) \ - SOC_DAPM_ENUM(xname, xenum) #define SOC_DAPM_PIN_SWITCH(xname) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ .info = snd_soc_dapm_info_pin_switch, \ diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..98e85a4796b6 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -196,8 +196,6 @@ .info = snd_soc_info_enum_double, \ .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ .private_value = (unsigned long)&xenum } -#define SOC_VALUE_ENUM(xname, xenum) \ - SOC_ENUM(xname, xenum) #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\ xhandler_get, xhandler_put) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ From e8304d04ac88c21b2a68d189f01678d71479a803 Mon Sep 17 00:00:00 2001 From: Steven Miao Date: Sat, 12 Apr 2014 09:23:24 +0800 Subject: [PATCH 0196/1034] spi: bfin5xx: fix build error should include linux/gpio.h Signed-off-by: Steven Miao Signed-off-by: Mark Brown --- drivers/spi/spi-bfin5xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 55e57c3eb9bd..ebf720b88a2a 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include From 40448e5e977b59a4753fce3619f537b63fcedc02 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 15:56:30 +0300 Subject: [PATCH 0197/1034] ASoC: davinci-mcasp: Do not touch 0x04 register above McASP_VERSION_2 This register is not defined in TI81xx and on AM335x/AM437x it is the SYSCONFIG register which should not be touched by drivers since it is related to PM and handled by the generic PM code. This register write was there since the first time the davinci-mcasp driver was appeared in the kernel. The reason why it did not caused any issues on AM335x/AM437x is that it sets bit 1 in SYSCONFIG register which in turn will enable the smart-idle mode. This is the default mode and this is the mode McASP should be in also when in use. On TI81xx the register is not defined. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 8007fcf428d9..af92d3e8671d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -502,7 +502,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int active_serializers, numevt, n; u32 reg; /* Default configuration */ - if (mcasp->version != MCASP_VERSION_4) + if (mcasp->version < MCASP_VERSION_3) mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); /* All PINS as McASP */ From 818e91625aa17161cd6b39a4d08b77c984f0f485 Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:57 +0800 Subject: [PATCH 0198/1034] spi: sirf: correct TXFIFO empty interrupt status bit the old code uses wrong marco - SIRFSOC_SPI_FIFO_FULL is not for FIFO interrupt status, it is for FIFO status. here in the ISR, SIRFSOC_SPI_TXFIFO_EMPTY is the right bit for SPI TXFIFO interrupt status. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 1a77ad52812f..51d7c988d3ae 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -287,8 +287,8 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) sspi->left_rx_word) sspi->rx_word(sspi); - if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY - | SIRFSOC_SPI_TXFIFO_THD_REACH)) + if (spi_stat & (SIRFSOC_SPI_TXFIFO_EMPTY | + SIRFSOC_SPI_TXFIFO_THD_REACH)) while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) & SIRFSOC_SPI_FIFO_FULL)) && sspi->left_tx_word) From 625227a4e916fa87f1dd84bde518ef403c3f708a Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:58 +0800 Subject: [PATCH 0199/1034] spi: sirf: set SPI controller in RISC IO chipselect mode SPI bitbang supply "chipselect" interface for change chip-select line , in the SiRFSoC SPI controller, we need to enable "SPI_CS_IO_MODE", otherwise, spi_sirfsoc_chipselect() has no effect. now the driver is working is because SPI controller will control CS automatically without SPI_CS_IO_MODE. this patch makes the CS controller really controlled by software. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 51d7c988d3ae..9b30743d816a 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -559,6 +559,11 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) regval &= ~SIRFSOC_SPI_CMD_MODE; sspi->tx_by_cmd = false; } + /* + * set spi controller in RISC chipselect mode, we are controlling CS by + * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. + */ + regval |= SIRFSOC_SPI_CS_IO_MODE; writel(regval, sspi->base + SIRFSOC_SPI_CTRL); if (IS_DMA_VALID(t)) { From 6ee8a2f7d5e78700b6e64799b5e9976b21cfad79 Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:59 +0800 Subject: [PATCH 0200/1034] spi: sirf: make GPIO chipselect function work well orignal GPIO chipslect is not standard because it don't take care to the chipselect signal: BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 9b30743d816a..67d8909dcf39 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -470,7 +470,16 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) writel(regval, sspi->base + SIRFSOC_SPI_CTRL); } else { int gpio = sspi->chipselect[spi->chip_select]; - gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); + switch (value) { + case BITBANG_CS_ACTIVE: + gpio_direction_output(gpio, + spi->mode & SPI_CS_HIGH ? 1 : 0); + break; + case BITBANG_CS_INACTIVE: + gpio_direction_output(gpio, + spi->mode & SPI_CS_HIGH ? 0 : 1); + break; + } } } From 3dedc5f5b11c567dbe2f31adb5119d1dfb8f51c9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 14 Apr 2014 10:41:36 +0900 Subject: [PATCH 0201/1034] ARM: shmobile: r8a7778: Use clks as MSTP007 parent According to the documentation the parent clock of MSTP007 should be clks not clkp. Signed-off-by: Simon Horman Acked-by: Laurent Pinchart Signed-off-by: Mark Brown --- arch/arm/mach-shmobile/clock-r8a7778.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 2009a9bc6356..9989b1b06ffd 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -170,7 +170,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ - [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ + [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0, 7, 0), /* HSPI */ }; static struct clk_lookup lookups[] = { From 4a4dd7d80e11f62cacf49bd90d9448a218188af7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 14 Apr 2014 10:41:38 +0900 Subject: [PATCH 0202/1034] spi: sh-hspi: Do not specifically request shyway_clk clock Rather than requesting the shyway_clk call clk_get with the device and a NULL con_id. This is in keeping with the way that clk_get() is called on other drivers used by Renesas Gen 1 SoCs. And I believe it is compatible with supplying clocks via DT, unlike the current code. It appears to me that the two uses of this driver are the r8a7778 and r8a7779 SoCs. The r8a7779 already has clocks setup to allow this driver to continue to work with this change applied. The r8a7778 has clocks incorrectly setup to allow this driver to continue to work with this change applied. This problem is addressed in "ARM: shmobile: r8a7778: Use clks as MSTP007 parent" which is thus a pre-requisite of this patch. Signed-off-by: Simon Horman Signed-off-by: Mark Brown --- drivers/spi/spi-sh-hspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 9009456bdf4d..c8e795ef2e13 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -244,9 +244,9 @@ static int hspi_probe(struct platform_device *pdev) return -ENOMEM; } - clk = clk_get(NULL, "shyway_clk"); + clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "shyway_clk is required\n"); + dev_err(&pdev->dev, "couldn't get clock\n"); ret = -EINVAL; goto error0; } From f84526cfae46672308a361333c76b724384b61ee Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 11 Apr 2014 22:10:00 +0800 Subject: [PATCH 0203/1034] ASoC: fsl_sai: Fix incorrect condition check in trigger() Patch ASoC: fsl_sai: Fix buggy configurations in trigger() doesn't entirely fix the condition: FRDE of the current substream direction is being cleared while the code is still using the non-updated one. Thus this patch fixes this issue by checking the opposite one's FRDE alone since the current one's is absolutely disabled. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 1c93282fbd26..a25e8884b09d 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -409,7 +409,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_xIE_MASK, 0); - if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + /* Check if the opposite FRDE is also disabled */ + if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { regmap_update_bits(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_TERE, 0); regmap_update_bits(sai->regmap, FSL_SAI_RCSR, From 3e185238a37d1f0a37a1d910344cdcff578bf333 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:26 +0800 Subject: [PATCH 0204/1034] ASoC: esai: use the precise definition of 'ret'. Use the precise definition of 'ret', which will be used for the error check. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index c8e5db1414d7..67d5417e0933 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -209,8 +209,9 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, struct clk *clksrc = esai_priv->extalclk; bool tx = clk_id <= ESAI_HCKT_EXTAL; bool in = dir == SND_SOC_CLOCK_IN; - u32 ret, ratio, ecr = 0; + u32 ratio, ecr = 0; unsigned long clk_rate; + int ret; /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ esai_priv->sck_div[tx] = true; @@ -432,8 +433,8 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int fsl_esai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int ret; struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + int ret; /* * Some platforms might use the same bit to gate all three or two of @@ -491,7 +492,8 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 width = snd_pcm_format_width(params_format(params)); u32 channels = params_channels(params); - u32 bclk, mask, val, ret; + u32 bclk, mask, val; + int ret; bclk = params_rate(params) * esai_priv->slot_width * 2; From add180ed780e9031d65e7c94cad936e719401acf Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:27 +0800 Subject: [PATCH 0205/1034] ASoC: spdif: Sort the header files alphabetically. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 6452ca83d889..173553c6dc55 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -13,18 +13,18 @@ * kind, whether express or implied. */ -#include +#include #include #include -#include -#include +#include #include #include #include +#include #include -#include #include +#include #include "fsl_spdif.h" #include "imx-pcm.h" From b21cc2f5fdfe22429501cd7040db0b2b2a9b29de Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:28 +0800 Subject: [PATCH 0206/1034] ASoC: esai: Add VF610+ compatibles support. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 67d5417e0933..b49b78df2f5b 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -818,6 +818,7 @@ static int fsl_esai_probe(struct platform_device *pdev) static const struct of_device_id fsl_esai_dt_ids[] = { { .compatible = "fsl,imx35-esai", }, + { .compatible = "fsl,vf610-esai", }, {} }; MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); From 1014fad0fca91181acc68396d84573e4ae301380 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:29 +0800 Subject: [PATCH 0207/1034] ASoC: spdif: Add VF610+ compatibles support. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 173553c6dc55..daa6198ae41f 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1186,6 +1186,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) static const struct of_device_id fsl_spdif_dt_ids[] = { { .compatible = "fsl,imx35-spdif", }, + { .compatible = "fsl,vf610-spdif", }, {} }; MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); From 2a266f8b2ae790454edb79cb8c707c9305e0307a Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 11 Apr 2014 18:30:09 +0800 Subject: [PATCH 0208/1034] ASoC: fsl_sai: Use FSL_SAI_xXR() and regmap_update_bits() to simplify code By doing this, the driver can drop around 50 lines and become neater. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 101 ++++++++++------------------------------ 1 file changed, 25 insertions(+), 76 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a25e8884b09d..c5a0e8af8226 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -119,16 +119,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int fsl_dir) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr2, reg_cr2; - - if (fsl_dir == FSL_FMT_TRANSMITTER) - reg_cr2 = FSL_SAI_TCR2; - else - reg_cr2 = FSL_SAI_RCR2; - - regmap_read(sai->regmap, reg_cr2, &val_cr2); - - val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; + bool tx = fsl_dir == FSL_FMT_TRANSMITTER; + u32 val_cr2 = 0; switch (clk_id) { case FSL_SAI_CLK_BUS: @@ -147,7 +139,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, return -EINVAL; } - regmap_write(sai->regmap, reg_cr2, val_cr2); + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), + FSL_SAI_CR2_MSEL_MASK, val_cr2); return 0; } @@ -179,22 +172,10 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, unsigned int fmt, int fsl_dir) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr2, val_cr4, reg_cr2, reg_cr4; + bool tx = fsl_dir == FSL_FMT_TRANSMITTER; + u32 val_cr2 = 0, val_cr4 = 0; - if (fsl_dir == FSL_FMT_TRANSMITTER) { - reg_cr2 = FSL_SAI_TCR2; - reg_cr4 = FSL_SAI_TCR4; - } else { - reg_cr2 = FSL_SAI_RCR2; - reg_cr4 = FSL_SAI_RCR4; - } - - regmap_read(sai->regmap, reg_cr2, &val_cr2); - regmap_read(sai->regmap, reg_cr4, &val_cr4); - - if (sai->big_endian_data) - val_cr4 &= ~FSL_SAI_CR4_MF; - else + if (!sai->big_endian_data) val_cr4 |= FSL_SAI_CR4_MF; /* DAI mode */ @@ -215,7 +196,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); break; case SND_SOC_DAIFMT_DSP_A: /* @@ -225,7 +205,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * data word. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~FSL_SAI_CR4_FSP; val_cr4 |= FSL_SAI_CR4_FSE; sai->is_dsp_mode = true; break; @@ -235,7 +214,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); sai->is_dsp_mode = true; break; case SND_SOC_DAIFMT_RIGHT_J: @@ -273,23 +251,22 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, val_cr4 |= FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBM_CFM: - val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; - val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBS_CFM: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; - val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBM_CFS: - val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; val_cr4 |= FSL_SAI_CR4_FSD_MSTR; break; default: return -EINVAL; } - regmap_write(sai->regmap, reg_cr2, val_cr2); - regmap_write(sai->regmap, reg_cr4, val_cr4); + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), + FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), + FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | + FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); return 0; } @@ -316,29 +293,10 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr; + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; unsigned int channels = params_channels(params); u32 word_width = snd_pcm_format_width(params_format(params)); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - reg_cr4 = FSL_SAI_TCR4; - reg_cr5 = FSL_SAI_TCR5; - reg_mr = FSL_SAI_TMR; - } else { - reg_cr4 = FSL_SAI_RCR4; - reg_cr5 = FSL_SAI_RCR5; - reg_mr = FSL_SAI_RMR; - } - - regmap_read(sai->regmap, reg_cr4, &val_cr4); - regmap_read(sai->regmap, reg_cr4, &val_cr5); - - val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; - val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; - - val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; - val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; - val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; + u32 val_cr4 = 0, val_cr5 = 0; if (!sai->is_dsp_mode) val_cr4 |= FSL_SAI_CR4_SYWD(word_width); @@ -346,18 +304,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, val_cr5 |= FSL_SAI_CR5_WNW(word_width); val_cr5 |= FSL_SAI_CR5_W0W(word_width); - val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; if (sai->big_endian_data) val_cr5 |= FSL_SAI_CR5_FBT(0); else val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); val_cr4 |= FSL_SAI_CR4_FRSZ(channels); - val_mr = ~0UL - ((1 << channels) - 1); - regmap_write(sai->regmap, reg_cr4, val_cr4); - regmap_write(sai->regmap, reg_cr5, val_cr5); - regmap_write(sai->regmap, reg_mr, val_mr); + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, + val_cr4); + regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), + FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | + FSL_SAI_CR5_FBT_MASK, val_cr5); + regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); return 0; } @@ -428,8 +388,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct device *dev = &sai->pdev->dev; - u32 reg; int ret; ret = clk_prepare_enable(sai->bus_clk); @@ -438,12 +398,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = FSL_SAI_TCR3; - else - reg = FSL_SAI_RCR3; - - regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, FSL_SAI_CR3_TRCE); return 0; @@ -453,15 +408,9 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 reg; + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = FSL_SAI_TCR3; - else - reg = FSL_SAI_RCR3; - - regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, - ~FSL_SAI_CR3_TRCE); + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); clk_disable_unprepare(sai->bus_clk); } From 1cb7b43f6796ad0bc62669fa52d1005916911d27 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 8 Mar 2014 11:55:29 +0800 Subject: [PATCH 0209/1034] regulator: pbias: Fix is_enabled callback implementation The is_enabled implementation is wrong in some cases: e.g. for pbias_mmc_omap5: enable_mask is : BIT(27) | BIT(25) | BIT(26) However, pbias_regulator_enable() only sets BIT(27) | BIT(26) bits. So is_enabled callback will always return false in this case. Fix the logic to compare the register value with info->enable rather than info->enable_mask. Signed-off-by: Axel Lin Acked-by: Balaji T K Signed-off-by: Mark Brown --- drivers/regulator/pbias-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index ded3b3574209..d89a1d8615c7 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -108,7 +108,7 @@ static int pbias_regulator_is_enable(struct regulator_dev *rdev) regmap_read(data->syscon, data->pbias_reg, &value); - return (value & info->enable_mask) == info->enable_mask; + return (value & info->enable_mask) == info->enable; } static struct regulator_ops pbias_regulator_voltage_ops = { From 60e8c1e34d3ab74556fb9b25f26fa34b9879ee30 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 8 Mar 2014 11:56:47 +0800 Subject: [PATCH 0210/1034] regulator: pbias: Convert to use regmap helper functions This patch converts this driver to use the regmap helper functions provided by regulator core. Signed-off-by: Axel Lin Acked-by: Balaji T K Signed-off-by: Mark Brown --- drivers/regulator/pbias-regulator.c | 74 ++++++++--------------------- 1 file changed, 19 insertions(+), 55 deletions(-) diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index d89a1d8615c7..6d38be3d970c 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -38,66 +38,24 @@ struct pbias_reg_info { struct pbias_regulator_data { struct regulator_desc desc; void __iomem *pbias_addr; - unsigned int pbias_reg; struct regulator_dev *dev; struct regmap *syscon; const struct pbias_reg_info *info; int voltage; }; -static int pbias_regulator_set_voltage(struct regulator_dev *dev, - int min_uV, int max_uV, unsigned *selector) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(dev); - const struct pbias_reg_info *info = data->info; - int ret, vmode; - - if (min_uV <= 1800000) - vmode = 0; - else if (min_uV > 1800000) - vmode = info->vmode; - - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->vmode, vmode); - - return ret; -} - -static int pbias_regulator_get_voltage(struct regulator_dev *rdev) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(rdev); - const struct pbias_reg_info *info = data->info; - int value, voltage; - - regmap_read(data->syscon, data->pbias_reg, &value); - value &= info->vmode; - - voltage = value ? 3000000 : 1800000; - - return voltage; -} +static const unsigned int pbias_volt_table[] = { + 1800000, + 3000000 +}; static int pbias_regulator_enable(struct regulator_dev *rdev) { struct pbias_regulator_data *data = rdev_get_drvdata(rdev); const struct pbias_reg_info *info = data->info; - int ret; - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->enable_mask, info->enable); - - return ret; -} - -static int pbias_regulator_disable(struct regulator_dev *rdev) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(rdev); - const struct pbias_reg_info *info = data->info; - int ret; - - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->enable_mask, 0); - return ret; + return regmap_update_bits(data->syscon, rdev->desc->enable_reg, + info->enable_mask, info->enable); } static int pbias_regulator_is_enable(struct regulator_dev *rdev) @@ -106,17 +64,18 @@ static int pbias_regulator_is_enable(struct regulator_dev *rdev) const struct pbias_reg_info *info = data->info; int value; - regmap_read(data->syscon, data->pbias_reg, &value); + regmap_read(data->syscon, rdev->desc->enable_reg, &value); return (value & info->enable_mask) == info->enable; } static struct regulator_ops pbias_regulator_voltage_ops = { - .set_voltage = pbias_regulator_set_voltage, - .get_voltage = pbias_regulator_get_voltage, - .enable = pbias_regulator_enable, - .disable = pbias_regulator_disable, - .is_enabled = pbias_regulator_is_enable, + .list_voltage = regulator_list_voltage_table, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = pbias_regulator_enable, + .disable = regulator_disable_regmap, + .is_enabled = pbias_regulator_is_enable, }; static const struct pbias_reg_info pbias_mmc_omap2430 = { @@ -192,6 +151,7 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (IS_ERR(syscon)) return PTR_ERR(syscon); + cfg.regmap = syscon; cfg.dev = &pdev->dev; for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { @@ -207,15 +167,19 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (!res) return -EINVAL; - drvdata[data_idx].pbias_reg = res->start; drvdata[data_idx].syscon = syscon; drvdata[data_idx].info = info; drvdata[data_idx].desc.name = info->name; drvdata[data_idx].desc.owner = THIS_MODULE; drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; + drvdata[data_idx].desc.volt_table = pbias_volt_table; drvdata[data_idx].desc.n_voltages = 2; drvdata[data_idx].desc.enable_time = info->enable_time; + drvdata[data_idx].desc.vsel_reg = res->start; + drvdata[data_idx].desc.vsel_mask = info->vmode; + drvdata[data_idx].desc.enable_reg = res->start; + drvdata[data_idx].desc.enable_mask = info->enable_mask; cfg.init_data = pbias_matches[idx].init_data; cfg.driver_data = &drvdata[data_idx]; From c39e1ef77c76729f34cdcb09bbb3a5096d91a740 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 12 Apr 2014 06:07:23 +0100 Subject: [PATCH 0211/1034] ARM: 8024/1: Keep DEBUG_UART_{PHYS,VIRT} entries sorted This patch sorts the entries for DEBUG_UART_{PHYS,VIRT}. Signed-off-by: Alexander Shiyan Signed-off-by: Russell King --- arch/arm/Kconfig.debug | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 4a2fc0bf6fc9..eab8ecbe69c1 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1030,9 +1030,9 @@ config DEBUG_UART_PHYS default 0x40100000 if DEBUG_PXA_UART1 default 0x42000000 if ARCH_GEMINI default 0x7c0003f8 if FOOTBRIDGE - default 0x80230000 if DEBUG_PICOXCELL_UART default 0x80070000 if DEBUG_IMX23_UART default 0x80074000 if DEBUG_IMX28_UART + default 0x80230000 if DEBUG_PICOXCELL_UART default 0x808c0000 if ARCH_EP93XX default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX @@ -1096,22 +1096,22 @@ config DEBUG_UART_VIRT default 0xfeb26000 if DEBUG_RK3X_UART1 default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 default 0xfeb31000 if DEBUG_KEYSTONE_UART1 - default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE - default 0xfed60000 if DEBUG_RK29_UART0 - default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 - default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0xfec02000 if DEBUG_SOCFPGA_UART + default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0 default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 default 0xfed12000 if ARCH_KIRKWOOD + default 0xfed60000 if DEBUG_RK29_UART0 + default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 + default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0xfedc0000 if ARCH_EP93XX default 0xfee003f8 if FOOTBRIDGE default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART - default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfee82340 if ARCH_IOP13XX default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN + default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfefff700 if ARCH_IOP33X default 0xff003000 if DEBUG_U300_UART default DEBUG_UART_PHYS if !MMU From 244b478386260a8a9150b501bc97644e2e07f8d3 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Mon, 14 Apr 2014 16:23:15 +0100 Subject: [PATCH 0212/1034] ARM: 8026/1: Fix emulation of multiply accumulate instructions The emulation for single and double precision multiply accumulate instructions correctly normalised any denormal values in the operand registers, but failed to normalise the destination (accumulator) register. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=70501 Signed-off-by: Jay Foad Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 2 ++ arch/arm/vfp/vfpsingle.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 6cac43bd1d86..423f56dd4028 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -866,6 +866,8 @@ vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, ch vdp.sign = vfp_sign_negate(vdp.sign); vfp_double_unpack(&vdn, vfp_get_double(dd)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); if (negate & NEG_SUBTRACT) vdn.sign = vfp_sign_negate(vdn.sign); diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index b252631b406b..4f96c1617aae 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -915,6 +915,8 @@ vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, cha v = vfp_get_float(sd); pr_debug("VFP: s%u = %08x\n", sd, v); vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); if (negate & NEG_SUBTRACT) vsn.sign = vfp_sign_negate(vsn.sign); From de66b584042b8f2cfe4c34ef4faa804dcd8d5843 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 14 Apr 2014 16:18:18 +0200 Subject: [PATCH 0213/1034] ARM: shmobile: sh73a0: drop address cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Simon Horman --- arch/arm/boot/dts/sh73a0.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index b7bd3b9a6753..5ecf552e1c00 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -34,7 +34,6 @@ gic: interrupt-controller@f0001000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; interrupt-controller; reg = <0xf0001000 0x1000>, <0xf0000100 0x100>; From 64c04a79c377e23449c59060727fcd34cc798eb6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 14 Apr 2014 16:18:17 +0200 Subject: [PATCH 0214/1034] ARM: shmobile: r8a7740: drop address cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7740.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 8280884bfa59..2551e9438d35 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -28,7 +28,6 @@ gic: interrupt-controller@c2800000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; interrupt-controller; reg = <0xc2800000 0x1000>, <0xc2000000 0x1000>; From d5dda0381f826326071b027f288372f682c24d55 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Apr 2014 19:13:21 +0900 Subject: [PATCH 0215/1034] ARM: shmobile: koelsch: correct renesas,gpios to renesas,groups in sd[012] pfc Fix typo of renesas,groups in the koeslch dt. The kernel has no renesas,gpios but this should match renesas,groups. Noticed thanks to similar fix for Lager by Rob Taylor and Ben Dooks. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index bdd73e6657b2..de1b6977c69a 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -230,17 +230,17 @@ }; sdhi0_pins: sd0 { - renesas,gpios = "sdhi0_data4", "sdhi0_ctrl"; + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; renesas,function = "sdhi0"; }; sdhi1_pins: sd1 { - renesas,gpios = "sdhi1_data4", "sdhi1_ctrl"; + renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; renesas,function = "sdhi1"; }; sdhi2_pins: sd2 { - renesas,gpios = "sdhi2_data4", "sdhi2_ctrl"; + renesas,groups = "sdhi2_data4", "sdhi2_ctrl"; renesas,function = "sdhi2"; }; From 4d4a0ff30c39b82c1dc549f2cc7a62b514431e64 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Apr 2014 19:35:57 +0200 Subject: [PATCH 0216/1034] ARM: shmobile: koelsch legacy: Enable Quad SPI transfers for the SPI FLASH Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-koelsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c index 5a034ff405d0..a12a9d3b4b6e 100644 --- a/arch/arm/mach-shmobile/board-koelsch.c +++ b/arch/arm/mach-shmobile/board-koelsch.c @@ -216,7 +216,7 @@ static const struct spi_board_info spi_info[] __initconst = { { .modalias = "m25p80", .platform_data = &spi_flash_data, - .mode = SPI_MODE_0, + .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, .max_speed_hz = 30000000, .bus_num = 0, .chip_select = 0, From a09b2f0ba170dc89a67d6c4c4f027b37a085dad9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Apr 2014 19:35:59 +0200 Subject: [PATCH 0217/1034] ARM: shmobile: lager legacy: Enable Quad SPI transfers for the SPI FLASH Signed-off-by: Geert Uytterhoeven Acked-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 6af09e1e0841..6c4fcfe5d9db 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -325,12 +325,12 @@ static const struct rspi_plat_data qspi_pdata __initconst = { static const struct spi_board_info spi_info[] __initconst = { { - .modalias = "m25p80", - .platform_data = &spi_flash_data, - .mode = SPI_MODE_0, - .max_speed_hz = 30000000, - .bus_num = 0, - .chip_select = 0, + .modalias = "m25p80", + .platform_data = &spi_flash_data, + .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, + .max_speed_hz = 30000000, + .bus_num = 0, + .chip_select = 0, }, }; From 17b9b3b9e88ac6564689283a08034faf2c048fdb Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Apr 2014 16:20:39 +0200 Subject: [PATCH 0218/1034] ARM: imx6q: clk: Parent DI clocks to video PLL via di_pre_sel Route the video PLL to the display interface clocks via the di_pre_sel and di_sel muxes by default. Signed-off-by: Sascha Hauer Signed-off-by: Philipp Zabel Tested-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 3ed67b592b48..4a6fb65589fa 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -445,6 +445,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); } + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]); + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]); + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]); + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]); + /* * The gpmi needs 100MHz frequency in the EDO/Sync mode, * We can not get the 100MHz from the pll2_pfd0_352m. From 4591b13289b54fb5cbce84ee170f7390c576ef8f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 14 Apr 2014 16:20:40 +0200 Subject: [PATCH 0219/1034] ARM: i.MX6: ipu_di_sel clocks can set parent rates To obtain exact pixel clocks, allow the DI clock selectors to influence the PLLs that they are derived from. Signed-off-by: Philipp Zabel Tested-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4a6fb65589fa..2b4d6acfa34a 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -258,14 +258,14 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); - clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels)); - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels)); - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels)); - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels)); + clk[ipu1_di0_pre_sel] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_pre_sel] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_pre_sel] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_pre_sel] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di0_sel] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_sel] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_sel] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_sel] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); From 036acea2ceabd19cb5734ae7a9d64c0a5ef90484 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 14 Apr 2014 23:36:15 -0400 Subject: [PATCH 0220/1034] ext4: fix ext4_count_free_clusters() with EXT4FS_DEBUG and bigalloc enabled With bigalloc enabled we must use EXT4_CLUSTERS_PER_GROUP() instead of EXT4_BLOCKS_PER_GROUP() otherwise we will go beyond the allocated buffer. $ mount -t ext4 /dev/vde /vde [ 70.573993] EXT4-fs DEBUG (fs/ext4/mballoc.c, 2346): ext4_mb_alloc_groupinfo: [ 70.575174] allocated s_groupinfo array for 1 meta_bg's [ 70.576172] EXT4-fs DEBUG (fs/ext4/super.c, 2092): ext4_check_descriptors: [ 70.576972] Checking group descriptorsBUG: unable to handle kernel paging request at ffff88006ab56000 [ 72.463686] IP: [] __bitmap_weight+0x2a/0x7f [ 72.464168] PGD 295e067 PUD 2961067 PMD 7fa8e067 PTE 800000006ab56060 [ 72.464738] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC [ 72.465139] Modules linked in: [ 72.465402] CPU: 1 PID: 3560 Comm: mount Tainted: G W 3.14.0-rc2-00069-ge57bce1 #60 [ 72.466079] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 72.466505] task: ffff88007ce6c8a0 ti: ffff88006b7f0000 task.ti: ffff88006b7f0000 [ 72.466505] RIP: 0010:[] [] __bitmap_weight+0x2a/0x7f [ 72.466505] RSP: 0018:ffff88006b7f1c00 EFLAGS: 00010206 [ 72.466505] RAX: 0000000000000000 RBX: 000000000000050a RCX: 0000000000000040 [ 72.466505] RDX: 0000000000000000 RSI: 0000000000080000 RDI: 0000000000000000 [ 72.466505] RBP: ffff88006b7f1c28 R08: 0000000000000002 R09: 0000000000000000 [ 72.466505] R10: 000000000000babe R11: 0000000000000400 R12: 0000000000080000 [ 72.466505] R13: 0000000000000200 R14: 0000000000002000 R15: ffff88006ab55000 [ 72.466505] FS: 00007f43ba1fa840(0000) GS:ffff88007f800000(0000) knlGS:0000000000000000 [ 72.466505] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 72.466505] CR2: ffff88006ab56000 CR3: 000000006b7e6000 CR4: 00000000000006e0 [ 72.466505] Stack: [ 72.466505] ffff88006ab65000 0000000000000000 0000000000000000 0000000000010000 [ 72.466505] ffff88006ab6f400 ffff88006b7f1c58 ffffffff81396bb8 0000000000010000 [ 72.466505] 0000000000000000 ffff88007b869a90 ffff88006a48a000 ffff88006b7f1c70 [ 72.466505] Call Trace: [ 72.466505] [] memweight+0x5f/0x8a [ 72.466505] [] ext4_count_free+0x13/0x21 [ 72.466505] [] ext4_count_free_clusters+0xdb/0x171 [ 72.466505] [] ext4_fill_super+0x117c/0x28ef [ 72.466505] [] ? vsnprintf+0x1c7/0x3f7 [ 72.466505] [] mount_bdev+0x145/0x19c [ 72.466505] [] ? ext4_calculate_overhead+0x2a1/0x2a1 [ 72.466505] [] ext4_mount+0x15/0x17 [ 72.466505] [] mount_fs+0x67/0x150 [ 72.466505] [] vfs_kern_mount+0x64/0xde [ 72.466505] [] do_mount+0x6fe/0x7f5 [ 72.466505] [] ? strndup_user+0x3a/0xd9 [ 72.466505] [] SyS_mount+0x85/0xbe [ 72.466505] [] tracesys+0xdd/0xe2 [ 72.466505] Code: c3 89 f0 b9 40 00 00 00 55 99 48 89 e5 41 57 f7 f9 41 56 49 89 ff 41 55 45 31 ed 41 54 41 89 f4 53 31 db 41 89 c6 45 39 ee 7e 10 <4b> 8b 3c ef 49 ff c5 e8 bf ff ff ff 01 c3 eb eb 31 c0 45 85 f6 [ 72.466505] RIP [] __bitmap_weight+0x2a/0x7f [ 72.466505] RSP [ 72.466505] CR2: ffff88006ab56000 [ 72.466505] ---[ end trace 7d051a08ae138573 ]--- Killed Signed-off-by: "Theodore Ts'o" --- fs/ext4/balloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6ea7b1436bbc..5c56785007e0 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -667,7 +667,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) continue; x = ext4_count_free(bitmap_bh->b_data, - EXT4_BLOCKS_PER_GROUP(sb) / 8); + EXT4_CLUSTERS_PER_GROUP(sb) / 8); printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", i, ext4_free_group_clusters(sb, gdp), x); bitmap_count += x; From 50e02fd84543d82e663000e780e0ec0cfde52283 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 14 Apr 2014 23:37:35 -0400 Subject: [PATCH 0221/1034] ext4: remove temporary shim used to merge COLLAPSE_RANGE and ZERO_RANGE In retrospect, this was a bad way to handle things, since it limited testing of these patches. We should just get the VFS level changes merged in first. Signed-off-by: "Theodore Ts'o" --- include/trace/events/ext4.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 010ea89eeb0e..6a1a0245474f 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -16,15 +16,6 @@ struct mpage_da_data; struct ext4_map_blocks; struct extent_status; -/* shim until we merge in the xfs_collapse_range branch */ -#ifndef FALLOC_FL_COLLAPSE_RANGE -#define FALLOC_FL_COLLAPSE_RANGE 0x08 -#endif - -#ifndef FALLOC_FL_ZERO_RANGE -#define FALLOC_FL_ZERO_RANGE 0x10 -#endif - #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode)) #define show_mballoc_flags(flags) __print_flags(flags, "|", \ From 6faff9b6bd3d2a279b806d721bb2257fdd2e6bf2 Mon Sep 17 00:00:00 2001 From: Max Schwarz Date: Sun, 9 Mar 2014 20:43:11 +0100 Subject: [PATCH 0222/1034] ARM: rockchip: rk3188: enable pull-ups on UART RX pins The default behaviour of the uart-rx pins on the rk3188 is to be pulled up and a lot of designs use diodes to even prevent them from being raised from the outside. Therefore change the rx-pin settings accordingly. This also fixes a uart receive problem on mass production Radxa Rock boards. Signed-off-by: Max Schwarz Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3188.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index bb36596ea205..ed9a70af3e3f 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -149,7 +149,7 @@ uart0 { uart0_xfer: uart0-xfer { - rockchip,pins = , + rockchip,pins = , ; }; @@ -164,7 +164,7 @@ uart1 { uart1_xfer: uart1-xfer { - rockchip,pins = , + rockchip,pins = , ; }; @@ -179,7 +179,7 @@ uart2 { uart2_xfer: uart2-xfer { - rockchip,pins = , + rockchip,pins = , ; }; /* no rts / cts for uart2 */ @@ -187,7 +187,7 @@ uart3 { uart3_xfer: uart3-xfer { - rockchip,pins = , + rockchip,pins = , ; }; From 9de98da2a7531ec9dedfbe95d69ee55237bbd9d5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 15 Apr 2014 07:46:05 +0200 Subject: [PATCH 0223/1034] ASoC: wm8997: Fix compile error The macro's name is SOC_ENUM, not SOC_VALUE. Fixes: e13dd8ce ("ASoC: wm8997: Replace usage deprecated MUX/ENUM macros") Reported-by: Stephen Rothwell Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index e45bbc0f15b2..a5dcdcb3ee24 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -245,8 +245,8 @@ SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), -SOC_VALUE("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -286,8 +286,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE("HPOUT1 OSR", wm8997_hpout_osr[0]), -SOC_VALUE("EPOUT OSR", wm8997_hpout_osr[1]), +SOC_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), +SOC_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), From 5c4348c1f959234664e4667f428cf82b3b8a7c2c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 11 Apr 2014 11:44:24 +0200 Subject: [PATCH 0224/1034] ARM: rockchip: fix copy'n'paste error in smp error messages The error emitted when mapping the pmu failed, wrongly mentions the sram. Reported-by: Kent Borg Signed-off-by: Heiko Stuebner --- arch/arm/mach-rockchip/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index dbfa5a26cfff..072842f6491b 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -152,7 +152,7 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); if (!node) { - pr_err("%s: could not find sram dt node\n", __func__); + pr_err("%s: could not find pmu dt node\n", __func__); return; } From f1c6bb2cb8b81013e8979806f8e15e3d53efb96d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 06:17:49 -0400 Subject: [PATCH 0225/1034] locks: allow __break_lease to sleep even when break_time is 0 A fl->fl_break_time of 0 has a special meaning to the lease break code that basically means "never break the lease". knfsd uses this to ensure that leases don't disappear out from under it. Unfortunately, the code in __break_lease can end up passing this value to wait_event_interruptible as a timeout, which prevents it from going to sleep at all. This makes __break_lease to spin in a tight loop and causes soft lockups. Fix this by ensuring that we pass a minimum value of 1 as a timeout instead. Cc: Cc: J. Bruce Fields Reported-by: Terry Barnaby Signed-off-by: Jeff Layton --- fs/locks.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 13fc7a6d380a..b380f5543614 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1391,11 +1391,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) restart: break_time = flock->fl_break_time; - if (break_time != 0) { + if (break_time != 0) break_time -= jiffies; - if (break_time == 0) - break_time++; - } + if (break_time == 0) + break_time++; locks_insert_block(flock, new_fl); spin_unlock(&inode->i_lock); error = wait_event_interruptible_timeout(new_fl->fl_wait, From 9c72a04ca78606bf10211efa93b3332c710afc65 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 15 Apr 2014 12:02:02 +0100 Subject: [PATCH 0226/1034] ASoC: fsl: Add explicit include of of.h Hopefully fixing a build failure reported by Stephen Rothwell - though quite why the other OF headers don't include this as well I'm not sure. Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..2fbbd8416c00 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include From f3046f86b8a455ae55b8d465cd34938006361096 Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Sun, 13 Apr 2014 19:56:36 +0200 Subject: [PATCH 0227/1034] ASoC: Intel: Fix incorrect sizeof() in sst_hsw_stream_get_volume() Fix an incorrect sizeof() usage in sst_hsw_stream_get_volume(). sst_dsp_read() is called to read into a variable of type u32, but is passed sizeof(u32 *) for argument 'size_t bytes'. Detected by Coverity: CID 1195260. Signed-off-by: Christian Engelmayer Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index f46bb4ddde6f..455a1857c441 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream return -EINVAL; sst_dsp_read(hsw->dsp, volume, - stream->reply.volume_register_address[channel], sizeof(volume)); + stream->reply.volume_register_address[channel], + sizeof(*volume)); return 0; } From dd1b94bf4920cc12545883faa43c014efbf61b1e Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Sun, 13 Apr 2014 22:46:31 +0200 Subject: [PATCH 0228/1034] ASoC: Intel: Fix a self assignment in sst_mem_block_alloc_scratch() Remove a self assignment in sst_mem_block_alloc_scratch(). When calculating buffer sizes there is no need for statements without effect. Detected by Coverity: CID 1195249. Signed-off-by: Christian Engelmayer Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index f7687107cf7f..f24619adc3d1 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -505,9 +505,7 @@ struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp) /* calculate required scratch size */ list_for_each_entry(sst_module, &dsp->module_list, list) { - if (scratch->s.size > sst_module->s.size) - scratch->s.size = scratch->s.size; - else + if (scratch->s.size < sst_module->s.size) scratch->s.size = sst_module->s.size; } From 3608aeff47034faee7518ddec52d77fb811e952c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 31 Mar 2014 19:52:44 +0200 Subject: [PATCH 0229/1034] pata_samsung_cf: fix ata_host_activate() failure handling Add missing clk_disable() call to ata_host_activate() failure path. Cc: Ben Dooks Cc: Kukjin Kim Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Jingoo Han Signed-off-by: Tejun Heo --- drivers/ata/pata_samsung_cf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index a79566d05666..0610e78c8a2a 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -594,9 +594,13 @@ static int __init pata_s3c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); - return ata_host_activate(host, info->irq, - info->irq ? pata_s3c_irq : NULL, - 0, &pata_s3c_sht); + ret = ata_host_activate(host, info->irq, + info->irq ? pata_s3c_irq : NULL, + 0, &pata_s3c_sht); + if (ret) + goto stop_clk; + + return 0; stop_clk: clk_disable(info->clk); From 3a7745215e7f73a5c7d9bcdc50661a55b39052a3 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 14 Apr 2014 22:02:30 +0200 Subject: [PATCH 0230/1034] dm verity: fix biovecs hash calculation regression Commit 003b5c5719f159f4f4bf97511c4702a0638313dd ("block: Convert drivers to immutable biovecs") incorrectly converted biovec iteration in dm-verity to always calculate the hash from a full biovec, but the function only needs to calculate the hash from part of the biovec (up to the calculated "todo" value). Fix this issue by limiting hash input to only the requested data size. This problem was identified using the cryptsetup regression test for veritysetup (verity-compat-test). Signed-off-by: Milan Broz Acked-by: Mikulas Patocka Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org # 3.14+ --- drivers/md/dm-verity.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c index 796007a5e0e1..7a7bab8947ae 100644 --- a/drivers/md/dm-verity.c +++ b/drivers/md/dm-verity.c @@ -330,15 +330,17 @@ test_block_hash: return r; } } - todo = 1 << v->data_dev_block_bits; - while (io->iter.bi_size) { + do { u8 *page; + unsigned len; struct bio_vec bv = bio_iter_iovec(bio, io->iter); page = kmap_atomic(bv.bv_page); - r = crypto_shash_update(desc, page + bv.bv_offset, - bv.bv_len); + len = bv.bv_len; + if (likely(len >= todo)) + len = todo; + r = crypto_shash_update(desc, page + bv.bv_offset, len); kunmap_atomic(page); if (r < 0) { @@ -346,8 +348,9 @@ test_block_hash: return r; } - bio_advance_iter(bio, &io->iter, bv.bv_len); - } + bio_advance_iter(bio, &io->iter, len); + todo -= len; + } while (todo); if (!v->version) { r = crypto_shash_update(desc, v->salt, v->salt_size); From 3063a12be2b07c64e9802708a19489342e64c1a3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 28 Mar 2014 14:31:47 -0500 Subject: [PATCH 0231/1034] usb: musb: fix PHY power on/off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commi 30a70b0 (usb: musb: fix obex in g_nokia.ko causing kernel panic) removed phy_power_on() and phy_power_off() calls from runtime PM callbacks but it failed to note that the driver depended on pm_runtime_get_sync() calls to power up the PHY, thus leaving some platforms without any means to have a working PHY. Fix that by enabling the phy during omap2430_musb_init() and killing it in omap2430_musb_exit(). Fixes: 30a70b0 (usb: musb: fix obex in g_nokia.ko causing kernel panic) Cc: # v3.14 Cc: Pali Rohár Cc: Ivaylo Dimitrov Reported-by: Michael Scott Tested-by: Michael Scott Tested-by: Stefan Roese Reported-by: Rabin Vincent Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index d341c149a2f9..819a7cdcb866 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -416,6 +416,7 @@ static int omap2430_musb_init(struct musb *musb) omap_musb_set_mailbox(glue); phy_init(musb->phy); + phy_power_on(musb->phy); pm_runtime_put_noidle(musb->controller); return 0; @@ -478,6 +479,7 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); + phy_power_off(musb->phy); phy_exit(musb->phy); return 0; From 8b2bc2c9351b4c09bc3d9096e2a7af3988565dbf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 7 Apr 2014 10:58:01 -0500 Subject: [PATCH 0232/1034] usb: musb: omap2430: make sure clocks are enabled when running mailbox on early initialization we could fall into a situation where the mailbox is called before MUSB's clocks are running, in order to avoid that, make sure mailbox is always wrapped with pm_runtime calls. Reported-by: Stefan Roese Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 819a7cdcb866..d369bf1f3936 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -316,7 +316,13 @@ static void omap_musb_mailbox_work(struct work_struct *mailbox_work) { struct omap2430_glue *glue = container_of(mailbox_work, struct omap2430_glue, omap_musb_mailbox_work); + struct musb *musb = glue_to_musb(glue); + struct device *dev = musb->controller; + + pm_runtime_get_sync(dev); omap_musb_set_mailbox(glue); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci) From 66097ca7889965e1b85de5cf699d7d728d84f47a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 15 Apr 2014 22:24:21 +0200 Subject: [PATCH 0233/1034] ASoC: Fix snd_soc_kcontrol_platform() return type This should obviously be snd_soc_platform * and not snd_soc_codec * Fixes: f6272ff8a5f4 ("ASoC: Add snd_soc_kcontrol_platform() helper function") Reported-by: kbuild test robot Reported-by: Stephen Rothwell Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 94a2dc20ad6e..81454b0dd624 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1253,7 +1253,7 @@ static inline struct snd_soc_codec *snd_soc_kcontrol_codec( * registered with snd_soc_add_platform_controls() or via table based setup of * a snd_soc_platform_driver. Otherwise the behavior is undefined. */ -static inline struct snd_soc_codec *snd_soc_kcontrol_platform( +static inline struct snd_soc_platform *snd_soc_kcontrol_platform( struct snd_kcontrol *kcontrol) { return snd_kcontrol_chip(kcontrol); From a1253ef6d3fabfe60838cd417b0624ab53df285e Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Tue, 15 Apr 2014 15:49:33 -0500 Subject: [PATCH 0234/1034] ASoC: cs42l51: split i2c from codec driver This patch removes the i2c bus code from the codec driver and creates seperate i2c driver. Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 6 ++- sound/soc/codecs/Makefile | 2 + sound/soc/codecs/cs42l51-i2c.c | 59 ++++++++++++++++++++++++++ sound/soc/codecs/cs42l51.c | 75 +++++++++------------------------- sound/soc/codecs/cs42l51.h | 5 +++ 5 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 sound/soc/codecs/cs42l51-i2c.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..5279ef41597d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -39,7 +39,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_ALC5623 if I2C select SND_SOC_ALC5632 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC - select SND_SOC_CS42L51 if I2C + select SND_SOC_CS42L51_I2C if I2C select SND_SOC_CS42L52 if I2C select SND_SOC_CS42L73 if I2C select SND_SOC_CS4270 if I2C @@ -280,6 +280,10 @@ config SND_SOC_CQ0093VC config SND_SOC_CS42L51 tristate +config SND_SOC_CS42L51_I2C + tristate + select SND_SOC_CS42L51 + config SND_SOC_CS42L52 tristate "Cirrus Logic CS42L52 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..e06f10032344 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -26,6 +26,7 @@ snd-soc-ak5386-objs := ak5386.o snd-soc-arizona-objs := arizona.o snd-soc-cq93vc-objs := cq93vc.o snd-soc-cs42l51-objs := cs42l51.o +snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o snd-soc-cs42l73-objs := cs42l73.o snd-soc-cs4270-objs := cs4270.o @@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o +obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c new file mode 100644 index 000000000000..cee51ae177c1 --- /dev/null +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -0,0 +1,59 @@ +/* + * cs42l56.c -- CS42L51 ALSA SoC I2C audio driver + * + * Copyright 2014 CirrusLogic, Inc. + * + * Author: Brian Austin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include "cs42l51.h" + +static struct i2c_device_id cs42l51_i2c_id[] = { + {"cs42l51", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); + +static int cs42l51_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap_config config; + + config = cs42l51_regmap; + config.val_bits = 8; + config.reg_bits = 8; + + return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config)); +} + +static int cs42l51_i2c_remove(struct i2c_client *i2c) +{ + snd_soc_unregister_codec(&i2c->dev); + + return 0; +} + +static struct i2c_driver cs42l51_i2c_driver = { + .driver = { + .name = "cs42l51", + .owner = THIS_MODULE, + }, + .probe = cs42l51_i2c_probe, + .remove = cs42l51_i2c_remove, + .id_table = cs42l51_i2c_id, +}; + +module_i2c_driver(cs42l51_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS42L51 I2C Driver"); +MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..46abd3e02f14 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include "cs42l51.h" @@ -483,7 +482,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { .ops = &cs42l51_dai_ops, }; -static int cs42l51_probe(struct snd_soc_codec *codec) +static int cs42l51_codec_probe(struct snd_soc_codec *codec) { int ret, reg; @@ -504,7 +503,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) } static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { - .probe = cs42l51_probe, + .probe = cs42l51_codec_probe, .controls = cs42l51_snd_controls, .num_controls = ARRAY_SIZE(cs42l51_snd_controls), @@ -514,91 +513,55 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), }; -static const struct regmap_config cs42l51_regmap = { - .reg_bits = 8, - .val_bits = 8, - +const struct regmap_config cs42l51_regmap = { .max_register = CS42L51_CHARGE_FREQ, .cache_type = REGCACHE_RBTREE, }; +EXPORT_SYMBOL_GPL(cs42l51_regmap); -static int cs42l51_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +int cs42l51_probe(struct device *dev, struct regmap *regmap) { struct cs42l51_private *cs42l51; - struct regmap *regmap; unsigned int val; int ret; - regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", - ret); - return ret; - } + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private), + GFP_KERNEL); + if (!cs42l51) + return -ENOMEM; + + dev_set_drvdata(dev, cs42l51); /* Verify that we have a CS42L51 */ ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); if (ret < 0) { - dev_err(&i2c_client->dev, "failed to read I2C\n"); + dev_err(dev, "failed to read I2C\n"); goto error; } if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { - dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); + dev_err(dev, "Invalid chip id: %x\n", val); ret = -ENODEV; goto error; } + dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", val & 0xFF); - dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", - val & 7); - - cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), - GFP_KERNEL); - if (!cs42l51) - return -ENOMEM; - - i2c_set_clientdata(i2c_client, cs42l51); - - ret = snd_soc_register_codec(&i2c_client->dev, + ret = snd_soc_register_codec(dev, &soc_codec_device_cs42l51, &cs42l51_dai, 1); error: return ret; } - -static int cs42l51_i2c_remove(struct i2c_client *client) -{ - snd_soc_unregister_codec(&client->dev); - return 0; -} - -static const struct i2c_device_id cs42l51_id[] = { - {"cs42l51", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, cs42l51_id); +EXPORT_SYMBOL_GPL(cs42l51_probe); static const struct of_device_id cs42l51_of_match[] = { { .compatible = "cirrus,cs42l51", }, { } }; MODULE_DEVICE_TABLE(of, cs42l51_of_match); - -static struct i2c_driver cs42l51_i2c_driver = { - .driver = { - .name = "cs42l51-codec", - .owner = THIS_MODULE, - .of_match_table = cs42l51_of_match, - }, - .id_table = cs42l51_id, - .probe = cs42l51_i2c_probe, - .remove = cs42l51_i2c_remove, -}; - -module_i2c_driver(cs42l51_i2c_driver); - MODULE_AUTHOR("Arnaud Patard "); MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index 2beeb171db4b..641ef18435b3 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h @@ -18,6 +18,11 @@ #ifndef _CS42L51_H #define _CS42L51_H +struct device; + +extern const struct regmap_config cs42l51_regmap; +int cs42l51_probe(struct device *dev, struct regmap *regmap); + #define CS42L51_CHIP_ID 0x1B #define CS42L51_CHIP_REV_A 0x00 #define CS42L51_CHIP_REV_B 0x01 From 32702e96a9f76ea0e0a1d218310d2ac1adbd2907 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 26 Mar 2014 10:31:44 -0700 Subject: [PATCH 0235/1034] usb: dwc3: gadget: Iterate only over valid endpoints Make dwc3_gadget_resize_tx_fifos() iterate only over IN endpoints that are actually present, based on the num_in_eps parameter. This terminates the loop so as to prevent dereferencing a potential NULL dwc->eps[i] where i >= (num_in_eps + num_out_eps). Signed-off-by: Jack Pham Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a740eac74d56..70715eeededd 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -187,15 +187,12 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) * improve this algorithm so that we better use the internal * FIFO space */ - for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) { - struct dwc3_ep *dep = dwc->eps[num]; - int fifo_number = dep->number >> 1; + for (num = 0; num < dwc->num_in_eps; num++) { + /* bit0 indicates direction; 1 means IN ep */ + struct dwc3_ep *dep = dwc->eps[(num << 1) | 1]; int mult = 1; int tmp; - if (!(dep->number & 1)) - continue; - if (!(dep->flags & DWC3_EP_ENABLED)) continue; @@ -224,8 +221,7 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", dep->name, last_fifo_depth, fifo_size & 0xffff); - dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number), - fifo_size); + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); last_fifo_depth += (fifo_size & 0xffff); } From 9c1b70361e0b38e4acb8e62b54da66538cb77ff2 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 26 Mar 2014 18:46:38 +0200 Subject: [PATCH 0236/1034] usb: gadget: zero: Fix SuperSpeed enumeration for alternate setting 1 It was impossible to enumerate on a SuperSpeed (XHCI) host with alternate setting = 1 due to the wrongly set 'bMaxBurst' field in the SuperSpeed Endpoint Companion descriptor. Testcase: modprobe -r usbtest; modprobe usbtest alt=1 modprobe g_zero plug device to SuperSpeed port on the host. Without this patch the host always complains like so "usb 12-2: Not enough bandwidth for new device state. usb 12-2: Not enough bandwidth for altsetting 1" Bug was introduced by commit cf9a08ae in v3.9 Fixes: cf9a08ae5aec (usb: gadget: convert source sink and loopback to new function interface) Cc: 3.9+ # 3.9+ Reviewed-by: Felipe Balbi Acked-by: Sebastian Andrzej Siewior Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/gadget/zero.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 9f170c53e3d9..134f354ede62 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -300,7 +300,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) ss_opts->isoc_interval = gzero_options.isoc_interval; ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; ss_opts->isoc_mult = gzero_options.isoc_mult; - ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket; + ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; ss_opts->bulk_buflen = gzero_options.bulk_buflen; func_ss = usb_get_function(func_inst_ss); From f45e5f00dacf09362a16339d372fcc96705e40c7 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 26 Mar 2014 11:43:09 +0200 Subject: [PATCH 0237/1034] usb: dwc3: core: Fix gadget for system suspend/resume During system resume, if the event buffers are not setup before the gadget controller starts then we start with invalid context and this can lead to bus access errors. This is especially true for platforms that loose the controller context during system suspend. e.g. AM437x. The following backtrace was found when the system is suspended and resumed with g_zero loaded on AM437x-evm (USB cable connected to host all the while). [ 120.981506] WARNING: CPU: 0 PID: 1656 at drivers/bus/omap_l3_noc.c:137 l3_interrupt_handler+0x198/0x28c() [ 120.981514] L3 custom error: MASTER:USB0 WR TARGET:GPMC [ 120.981638] Modules linked in: g_mass_storage usb_f_mass_storage libcomposite configfs bufferclass_ti(O) omaplfb(O) cryptodev(O) dwc3 snd_soc_evm snd_soc_omap snd_pe [ 120.981659] CPU: 0 PID: 1656 Comm: sh Tainted: G O 3.12.10-gc559824 #1 [ 120.981669] Backtrace: [ 120.981705] [] (dump_backtrace+0x0/0x10c) from [] (show_stack+0x18/0x1c) [ 120.981730] r6:c02819ac r5:00000009 r4:ec137cb8 r3:00000000 [ 120.981767] [] (show_stack+0x0/0x1c) from [] (dump_stack+0x20/0x28) [ 120.981802] [] (dump_stack+0x0/0x28) from [] (warn_slowpath_common+0x70/0x90) [ 120.981830] [] (warn_slowpath_common+0x0/0x90) from [] (warn_slowpath_fmt+0x38/0x40) [ 120.981856] r8:c0855eb0 r7:00000002 r6:f1000700 r5:00000007 r4:80080003 [ 120.981886] [] (warn_slowpath_fmt+0x0/0x40) from [] (l3_interrupt_handler+0x198/0x28c) [ 120.981900] r3:c0801ab8 r2:c06cb354 [ 120.981936] [] (l3_interrupt_handler+0x0/0x28c) from [] (handle_irq_event_percpu+0x54/0x1b8) [ 120.981962] [] (handle_irq_event_percpu+0x0/0x1b8) from [] (handle_irq_event+0x30/0x40) [ 120.981993] [] (handle_irq_event+0x0/0x40) from [] (handle_fasteoi_irq+0x74/0x128) [ 120.982006] r4:ed0056c0 r3:00000000 [ 120.982033] [] (handle_fasteoi_irq+0x0/0x128) from [] (generic_handle_irq+0x28/0x38) [ 120.982046] r4:0000002a r3:c0073fe4 [ 120.982085] [] (generic_handle_irq+0x0/0x38) from [] (handle_IRQ+0x38/0x8c) [ 120.982098] r4:c080137c r3:00000182 [ 120.982124] [] (handle_IRQ+0x0/0x8c) from [] (gic_handle_irq+0x30/0x5c) [ 120.982145] r6:ec137dd0 r5:c07ac480 r4:fa24010c r3:00000100 [ 120.982169] [] (gic_handle_irq+0x0/0x5c) from [] (__irq_svc+0x40/0x54) [ 120.982179] Exception stack(0xec137dd0 to 0xec137e18) [ 120.982195] 7dc0: 00000000 a00001d3 00000000 00000004 [ 120.982216] 7de0: a0000153 ec1d9010 c080de90 ec137e30 c080debc 00000000 ed756e44 ec137e2c [ 120.982232] 7e00: ec137de0 ec137e18 bf1150e4 bf115474 60000153 ffffffff [ 120.982253] r7:ec137e04 r6:ffffffff r5:60000153 r4:bf115474 [ 120.982327] [] (dwc3_complete+0x0/0x40 [dwc3]) from [] (dpm_complete+0xd4/0x19c) [ 120.982341] r5:ed756e10 r4:ed756e64 [ 120.982370] [] (dpm_complete+0x0/0x19c) from [] (dpm_resume_end+0x1c/0x20) [ 120.982400] [] (dpm_resume_end+0x0/0x20) from [] (suspend_devices_and_enter+0x118/0x33c) [ 120.982412] r4:c0833da4 r3:00000000 [ 120.982436] [] (suspend_devices_and_enter+0x0/0x33c) from [] (pm_suspend+0x218/0x254) [ 120.982458] [] (pm_suspend+0x0/0x254) from [] (state_store+0x70/0xc0) [ 120.982478] r6:c057a6cc r5:c06a8320 r4:00000003 r3:0000006d [ 120.982515] [] (state_store+0x0/0xc0) from [] (kobj_attr_store+0x1c/0x28) [ 120.982546] [] (kobj_attr_store+0x0/0x28) from [] (sysfs_write_file+0x170/0x1a4) [ 120.982583] [] (sysfs_write_file+0x0/0x1a4) from [] (vfs_write+0xb8/0x190) [ 120.982611] [] (vfs_write+0x0/0x190) from [] (SyS_write+0x44/0x78) [ 120.982641] [] (SyS_write+0x0/0x78) from [] (ret_fast_syscall+0x0/0x30) Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index d001417e8e37..10aaaae9af25 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -821,6 +821,7 @@ static void dwc3_complete(struct device *dev) spin_lock_irqsave(&dwc->lock, flags); + dwc3_event_buffers_setup(dwc); switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: case USB_DR_MODE_OTG: @@ -828,7 +829,6 @@ static void dwc3_complete(struct device *dev) /* FALLTHROUGH */ case USB_DR_MODE_HOST: default: - dwc3_event_buffers_setup(dwc); break; } From 5cdf7d5be8443ba0e14a5cfe551c59f931983647 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 27 Mar 2014 08:09:21 +0100 Subject: [PATCH 0238/1034] usb: gadget: gadgetfs: Initialize CHIP to NULL before UDC probe Otherwise the value from the last probe would be retained that possibly is freed since (the UDC is removed) and therefore no longer relevant. Reproducible with the dummy UDC: modprobe dummy_hcd mount -t gadgetfs gadgetfs /dev/gadget umount /dev/gadget rmmod dummy_hcd mount -t gadgetfs gadgetfs /dev/gadget BUG: unable to handle kernel paging request at ffffffffa066fd9d Call Trace: [] ? d_alloc_name+0x22/0x50 [] ? selinux_d_instantiate+0x1c/0x20 [] gadgetfs_create_file+0x27/0xa0 [gadgetfs] [] ? setup_req.isra.4+0x80/0x80 [gadgetfs] [] gadgetfs_fill_super+0x13c/0x180 [gadgetfs] [] mount_single+0x92/0xc0 [] gadgetfs_mount+0x18/0x20 [gadgetfs] [] mount_fs+0x39/0x1b0 [] ? __alloc_percpu+0x10/0x20 [] vfs_kern_mount+0x63/0xf0 [] do_mount+0x23e/0xac0 [] ? strndup_user+0x4b/0xf0 [] SyS_mount+0x83/0xc0 [] system_call_fastpath+0x16/0x1b Signed-off-by: Lubomir Rintel Signed-off-by: Felipe Balbi --- drivers/usb/gadget/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index b5be6f0308c2..a925d0cbcd41 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -2043,6 +2043,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) return -ESRCH; /* fake probe to determine $CHIP */ + CHIP = NULL; usb_gadget_probe_driver(&probe_driver); if (!CHIP) return -ENODEV; From 0fca91b8a446d4a38b8f3d4772c4a8665ebcd7b2 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 2 Apr 2014 11:46:51 +0200 Subject: [PATCH 0239/1034] usb: musb: dsps: move debugfs_remove_recursive() When the platform initialization fails due to missing resources, it will return -EPROBE_DEFER after dsps_musb_init() has been called. dsps_musb_init() calls dsps_musb_dbg_init() to allocate the debugfs nodes. At a later point in time, the probe will be retried, and dsps_musb_dbg_init() will be called again. debugfs_create_dir() will fail this time, as the node already exists, and so the entire device probe will fail with -ENOMEM. Fix this by moving debugfs_remove_recursive() from dsps_remove() to the plaform's exit function, so it will be cleanly torn down when the probe fails. It also feels more natural this way, as .exit is the counterpart to .init. Signed-off-by: Daniel Mack Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 3372ded5def7..e2fd263585de 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -470,8 +470,9 @@ static int dsps_musb_exit(struct musb *musb) struct dsps_glue *glue = dev_get_drvdata(dev->parent); del_timer_sync(&glue->timer); - usb_phy_shutdown(musb->xceiv); + debugfs_remove_recursive(glue->dbgfs_root); + return 0; } @@ -708,8 +709,6 @@ static int dsps_remove(struct platform_device *pdev) pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - debugfs_remove_recursive(glue->dbgfs_root); - return 0; } From fc696881c6ec991f39a2f93d41f9ae841c6ace38 Mon Sep 17 00:00:00 2001 From: Suresh Gupta Date: Wed, 2 Apr 2014 22:26:46 +0530 Subject: [PATCH 0240/1034] usb : gadget : fsl: fix the fault issue on rmmod completion in udc_controller->done should be assign with proper value before complete called. The complete called in fsl_udc_release which intern called from usb_del_gadget_udc, so moving assignment before calling usb_del_gadget_udc Signed-off-by: Suresh Gupta Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 15960af0f67e..dcd0b07ae3a0 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2532,8 +2532,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) if (!udc_controller) return -ENODEV; - usb_del_gadget_udc(&udc_controller->gadget); udc_controller->done = &done; + usb_del_gadget_udc(&udc_controller->gadget); fsl_udc_clk_release(); From ae8dd0cc4146740e24ffb2092530c47e838001c5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 4 Apr 2014 22:27:59 -0300 Subject: [PATCH 0241/1034] usb: gadget: rndis: Include "u_rndis.h" Include "u_rndis.h" in order to fix the following sparse warning: drivers/usb/gadget/rndis.c:1144:5: warning: symbol 'rndis_init' was not declared. Should it be static? drivers/usb/gadget/rndis.c:1177:6: warning: symbol 'rndis_exit' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Felipe Balbi --- drivers/usb/gadget/rndis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index d822d822efb3..7ed452d90f4d 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -35,6 +35,7 @@ #include #include +#include "u_rndis.h" #undef VERBOSE_DEBUG From 9dc9cb0c9ad0f999e29ce4c4f307cd2abbe752d3 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 15 Apr 2014 07:58:15 +0200 Subject: [PATCH 0242/1034] usb: phy: return an error in usb_get_phy() if try_module_get() fails In case we found a matching USB PHY in usb_get_phy() but the call to try_module_get() fails, we shouldn't return a (probably soon dangling) pointer but an ERR_PTR instead. Signed-off-by: Mathias Krause Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 8afa813d690b..36b6bce33b20 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -132,6 +132,9 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { pr_debug("PHY: unable to find transceiver of type %s\n", usb_phy_type_string(type)); + if (!IS_ERR(phy)) + phy = ERR_PTR(-ENODEV); + goto err0; } From 97839ca4b06ab27790700ad7da6be9a75fc0cc1d Mon Sep 17 00:00:00 2001 From: Chao Bi Date: Mon, 14 Apr 2014 11:19:53 +0800 Subject: [PATCH 0243/1034] usb: gadget: ffs: race between ffs_epfile_io() and ffs_func_eps_disable() ffs_epfile_io() is called from userspace, while ffs_func_eps_disable() might be called from USB disconnect interrupt, the two functions would run in parallel but they are not well protected, that epfile->ep would be removed by ffs_func_eps_disable() during ffs_epfile_io() is referring this pointer, then it leads to kernel PANIC. The scenario is as below: Thread 1 Thread 2 | | SyS_read dwc3_gadget_disconnect_interrupt | | ffs_epfile_read reset_config | | ffs_epfile_io ffs_func_eps_disable | | ----- usb_ep_disable(): epfile->ep->ep->desc = NULL | | usb_ep_align_maybe(): ----- it refers ep->desc->wMaxPacketSize ----- Signed-off-by: Chao Bi Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 2e164dca08e8..1e12b3ee56fd 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -745,6 +745,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) */ struct usb_gadget *gadget = epfile->ffs->gadget; + spin_lock_irq(&epfile->ffs->eps_lock); + /* In the meantime, endpoint got disabled or changed. */ + if (epfile->ep != ep) { + spin_unlock_irq(&epfile->ffs->eps_lock); + return -ESHUTDOWN; + } /* * Controller may require buffer size to be aligned to * maxpacketsize of an out endpoint. @@ -752,6 +758,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) data_len = io_data->read ? usb_ep_align_maybe(gadget, ep->ep, io_data->len) : io_data->len; + spin_unlock_irq(&epfile->ffs->eps_lock); data = kmalloc(data_len, GFP_KERNEL); if (unlikely(!data)) From 9ae794ac5e407d3bc3fec785db481d5a2c0fa275 Mon Sep 17 00:00:00 2001 From: David Milburn Date: Wed, 16 Apr 2014 11:43:46 -0500 Subject: [PATCH 0244/1034] ahci: do not request irq for dummy port System may crash in ahci_hw_interrupt() or ahci_thread_fn() when accessing the interrupt status in a port's private_data if the port is actually a DUMMY port. 00:1f.2 SATA controller: Intel Corporation 82801JI (ICH10 Family) SATA AHCI Controller [ 9.352080] ahci 0000:00:1f.2: AHCI 0001.0200 32 slots 6 ports 3 Gbps 0x1 impl SATA mode [ 9.352084] ahci 0000:00:1f.2: flags: 64bit ncq sntf pm led clo pio slum part ccc [ 9.368155] Console: switching to colour frame buffer device 128x48 [ 9.439759] mgag200 0000:11:00.0: fb0: mgadrmfb frame buffer device [ 9.446765] mgag200 0000:11:00.0: registered panic notifier [ 9.470166] scsi1 : ahci [ 9.479166] scsi2 : ahci [ 9.488172] scsi3 : ahci [ 9.497174] scsi4 : ahci [ 9.506175] scsi5 : ahci [ 9.515174] scsi6 : ahci [ 9.518181] ata1: SATA max UDMA/133 abar m2048@0x95c00000 port 0x95c00100 irq 91 [ 9.526448] ata2: DUMMY [ 9.529182] ata3: DUMMY [ 9.531916] ata4: DUMMY [ 9.534650] ata5: DUMMY [ 9.537382] ata6: DUMMY [ 9.576196] [drm] Initialized mgag200 1.0.0 20110418 for 0000:11:00.0 on minor 0 [ 9.845257] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) [ 9.865161] ata1.00: ATAPI: Optiarc DVD RW AD-7580S, FX04, max UDMA/100 [ 9.891407] ata1.00: configured for UDMA/100 [ 9.900525] scsi 1:0:0:0: CD-ROM Optiarc DVD RW AD-7580S FX04 PQ: 0 ANSI: 5 [ 10.247399] iTCO_vendor_support: vendor-support=0 [ 10.261572] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11 [ 10.269764] iTCO_wdt: unable to reset NO_REBOOT flag, device disabled by hardware/BIOS [ 10.301932] sd 0:2:0:0: [sda] 570310656 512-byte logical blocks: (291 GB/271 GiB) [ 10.317085] sd 0:2:0:0: [sda] Write Protect is off [ 10.328326] sd 0:2:0:0: [sda] Write cache: disabled, read cache: disabled, supports DPO and FUA [ 10.375452] BUG: unable to handle kernel NULL pointer dereference at 000000000000003c [ 10.384217] IP: [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.392101] PGD 0 [ 10.394353] Oops: 0000 [#1] SMP [ 10.397978] Modules linked in: sr_mod(+) cdrom sd_mod iTCO_wdt crc_t10dif iTCO_vendor_support crct10dif_common ahci libahci libata lpc_ich mfd_core mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit drm_kms_helper ttm drm i2c_core megaraid_sas dm_mirror dm_region_hash dm_log dm_mod [ 10.426499] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.15.0-rc1 #1 [ 10.433495] Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.S013.032920111005 03/29/2011 [ 10.443886] task: ffffffff81906460 ti: ffffffff818f0000 task.ti: ffffffff818f0000 [ 10.452239] RIP: 0010:[] [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.462838] RSP: 0018:ffff880033c03d98 EFLAGS: 00010046 [ 10.468767] RAX: 0000000000a400a4 RBX: ffff880029a6bc18 RCX: 00000000fffffffa [ 10.476731] RDX: 00000000000000a4 RSI: ffff880029bb0000 RDI: ffff880029a6bc18 [ 10.484696] RBP: ffff880033c03dc8 R08: 0000000000000000 R09: ffff88002f800490 [ 10.492661] R10: 0000000000000000 R11: 0000000000000005 R12: 0000000000000000 [ 10.500625] R13: ffff880029a6bd98 R14: 0000000000000000 R15: ffffc90000194000 [ 10.508590] FS: 0000000000000000(0000) GS:ffff880033c00000(0000) knlGS:0000000000000000 [ 10.517623] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 10.524035] CR2: 000000000000003c CR3: 00000000328ff000 CR4: 00000000000007b0 [ 10.531999] Stack: [ 10.534241] 0000000000000017 ffff880031ba7d00 000000000000005c ffff880031ba7d00 [ 10.542535] 0000000000000000 000000000000005c ffff880033c03e10 ffffffff810c2a1e [ 10.550827] ffff880031ae2900 000000008108fb4f ffff880031ae2900 ffff880031ae2984 [ 10.559121] Call Trace: [ 10.561849] [ 10.563994] [] handle_irq_event_percpu+0x3e/0x1a0 [ 10.571309] [] handle_irq_event+0x3d/0x60 [ 10.577631] [] try_one_irq.isra.6+0x8d/0xf0 [ 10.584142] [] note_interrupt+0x173/0x1f0 [ 10.590460] [] handle_irq_event_percpu+0xae/0x1a0 [ 10.597554] [] handle_irq_event+0x3d/0x60 [ 10.603872] [] handle_edge_irq+0x77/0x130 [ 10.610199] [] handle_irq+0xbf/0x150 [ 10.616040] [] ? vtime_account_idle+0xe/0x50 [ 10.622654] [] ? atomic_notifier_call_chain+0x1a/0x20 [ 10.630140] [] do_IRQ+0x4f/0xf0 [ 10.635490] [] common_interrupt+0x6d/0x6d [ 10.641805] [ 10.643950] [] ? cpuidle_enter_state+0x4f/0xc0 [ 10.650972] [] ? cpuidle_enter_state+0x48/0xc0 [ 10.657775] [] cpuidle_enter+0x17/0x20 [ 10.663807] [] cpu_startup_entry+0x2c0/0x3d0 [ 10.670423] [] rest_init+0x77/0x80 [ 10.676065] [] start_kernel+0x40f/0x41a [ 10.682190] [] ? repair_env_string+0x5c/0x5c [ 10.688799] [] ? early_idt_handlers+0x120/0x120 [ 10.695699] [] x86_64_start_reservations+0x2a/0x2c [ 10.702889] [] x86_64_start_kernel+0x143/0x152 [ 10.709689] Code: a0 fc ff 85 c0 8b 4d d4 74 c3 48 8b 7b 08 89 ca 48 c7 c6 60 66 13 a0 31 c0 e8 9d 70 28 e1 8b 4d d4 eb aa 0f 1f 84 00 00 00 00 00 <45> 8b 64 24 3c 48 89 df e8 23 47 4c e1 41 83 fc 01 19 c0 48 83 [ 10.731470] RIP [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.739441] RSP [ 10.743333] CR2: 000000000000003c [ 10.747032] ---[ end trace b6e82636970e2690 ]--- [ 10.760190] Kernel panic - not syncing: Fatal exception in interrupt [ 10.767291] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff) Cc: Alexander Gordeev Cc: Tejun Heo Cc: Signed-of-by: David Milburn Fixes: 5ca72c4f7c41 ("AHCI: Support multiple MSIs") --- drivers/ata/ahci.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5a0bf8ed649b..e45b18ee04c3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1232,18 +1232,14 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) return rc; for (i = 0; i < host->n_ports; i++) { - const char* desc; struct ahci_port_priv *pp = host->ports[i]->private_data; /* pp is NULL for dummy ports */ if (pp) - desc = pp->irq_desc; - else - desc = dev_driver_string(host->dev); - - rc = devm_request_threaded_irq(host->dev, - irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED, - desc, host->ports[i]); + rc = devm_request_threaded_irq(host->dev, + irq + i, ahci_hw_interrupt, + ahci_thread_fn, IRQF_SHARED, + pp->irq_desc, host->ports[i]); if (rc) goto out_free_irqs; } From e02ba72aabfade4c9cd6e3263e9b57bf890ad25c Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Tue, 15 Apr 2014 11:31:33 -0700 Subject: [PATCH 0245/1034] aio: block io_destroy() until all context requests are completed deletes aio context and all resources related to. It makes sense that no IO operations connected to the context should be running after the context is destroyed. As we removed io_context we have no chance to get requests status or call io_getevents(). man page for io_destroy says that this function may block until all context's requests are completed. Before kernel 3.11 io_destroy() blocked indeed, but since aio refactoring in 3.11 it is not true anymore. Here is a pseudo-code that shows a testcase for a race condition discovered in 3.11: initialize io_context io_submit(read to buffer) io_destroy() // context is destroyed so we can free the resources free(buffers); // if the buffer is allocated by some other user he'll be surprised // to learn that the buffer still filled by an outstanding operation // from the destroyed io_context The fix is straight-forward - add a completion struct and wait on it in io_destroy, complete() should be called when number of in-fligh requests reaches zero. If two or more io_destroy() called for the same context simultaneously then only the first one waits for IO completion, other calls behaviour is undefined. Tested: ran http://pastebin.com/LrPsQ4RL testcase for several hours and do not see the race condition anymore. Signed-off-by: Anatol Pomozov Signed-off-by: Benjamin LaHaise --- fs/aio.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 12a3de0ee6da..2adbb0398ab9 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -112,6 +112,11 @@ struct kioctx { struct work_struct free_work; + /* + * signals when all in-flight requests are done + */ + struct completion *requests_done; + struct { /* * This counts the number of available slots in the ringbuffer, @@ -508,6 +513,10 @@ static void free_ioctx_reqs(struct percpu_ref *ref) { struct kioctx *ctx = container_of(ref, struct kioctx, reqs); + /* At this point we know that there are no any in-flight requests */ + if (ctx->requests_done) + complete(ctx->requests_done); + INIT_WORK(&ctx->free_work, free_ioctx); schedule_work(&ctx->free_work); } @@ -718,7 +727,8 @@ err: * when the processes owning a context have all exited to encourage * the rapid destruction of the kioctx. */ -static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) +static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, + struct completion *requests_done) { if (!atomic_xchg(&ctx->dead, 1)) { struct kioctx_table *table; @@ -747,7 +757,11 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) if (ctx->mmap_size) vm_munmap(ctx->mmap_base, ctx->mmap_size); + ctx->requests_done = requests_done; percpu_ref_kill(&ctx->users); + } else { + if (requests_done) + complete(requests_done); } } @@ -809,7 +823,7 @@ void exit_aio(struct mm_struct *mm) */ ctx->mmap_size = 0; - kill_ioctx(mm, ctx); + kill_ioctx(mm, ctx, NULL); } } @@ -1185,7 +1199,7 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) if (!IS_ERR(ioctx)) { ret = put_user(ioctx->user_id, ctxp); if (ret) - kill_ioctx(current->mm, ioctx); + kill_ioctx(current->mm, ioctx, NULL); percpu_ref_put(&ioctx->users); } @@ -1203,8 +1217,22 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) { struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { - kill_ioctx(current->mm, ioctx); + struct completion requests_done = + COMPLETION_INITIALIZER_ONSTACK(requests_done); + + /* Pass requests_done to kill_ioctx() where it can be set + * in a thread-safe way. If we try to set it here then we have + * a race condition if two io_destroy() called simultaneously. + */ + kill_ioctx(current->mm, ioctx, &requests_done); percpu_ref_put(&ioctx->users); + + /* Wait until all IO for the context are done. Otherwise kernel + * keep using user-space buffers even if user thinks the context + * is destroyed. + */ + wait_for_completion(&requests_done); + return 0; } pr_debug("EINVAL: io_destroy: invalid context id\n"); From 06cd7a874ec6e09d151aeb1fa8600e14f1ff89f6 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Apr 2014 20:08:01 +0200 Subject: [PATCH 0246/1034] s390/chsc: fix SEI usage on old FW levels Using a notification type mask for the store event information chsc is unsupported on some firmware levels. Retry SEI with that mask set to zero (which is the old way of requesting only channel subsystem related events). Cc: Reported-and-tested-by: Stefan Haberland Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 9f0ea6cb6922..e3bf885f4a6c 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -541,18 +541,27 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm) { - do { + static int ntsm_unsupported; + + while (true) { memset(sei, 0, sizeof(*sei)); sei->request.length = 0x0010; sei->request.code = 0x000e; - sei->ntsm = ntsm; + if (!ntsm_unsupported) + sei->ntsm = ntsm; if (chsc(sei)) break; if (sei->response.code != 0x0001) { - CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", - sei->response.code); + CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x, ntsm=%llx)\n", + sei->response.code, sei->ntsm); + + if (sei->response.code == 3 && sei->ntsm) { + /* Fallback for old firmware. */ + ntsm_unsupported = 1; + continue; + } break; } @@ -568,7 +577,10 @@ static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm) CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt); break; } - } while (sei->u.nt0_area.flags & 0x80); + + if (!(sei->u.nt0_area.flags & 0x80)) + break; + } } /* From ab0f9e78b97f5193dd38b3757b42b6fbded05fb7 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 17 Apr 2014 14:13:49 +0200 Subject: [PATCH 0247/1034] ahci: Ensure "MSI Revert to Single Message" mode is not enforced The AHCI specification allows hardware to choose to revert to single MSI mode when fewer messages are allocated than requested. Yet, at least ICH10 chipset reverts to single MSI mode even when enough messages are allocated in some cases (see below). This update forces the driver to not rely on initialization of multiple MSIs mode alone and always check if "MSI Revert to Single Message" (MRSM) mode was enforced by the controller and fallback to the single MSI mode in case it did. That prevents a situation when the driver configured multiple per-port IRQ handlers, but the controller sends all port's interrupts to a single IRQ, which could easily screw up the interrupt handling and lead to delays and possibly crashes. The fix was tested on a 6-port controller that successfully reverted to the single MSI mode: 00:1f.2 SATA controller: Intel Corporation 82801JI (ICH10 Family) SATA AHCI Controller (prog-if 01 [AHCI 1.0]) Subsystem: Super Micro Computer Inc Device 10a7 Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 101 I/O ports at f110 [size=8] I/O ports at f100 [size=4] I/O ports at f0f0 [size=8] I/O ports at f0e0 [size=4] I/O ports at f020 [size=32] Memory at fbf00000 (32-bit, non-prefetchable) [size=2K] Capabilities: [80] MSI: Enable+ Count=1/16 Maskable- 64bit- Capabilities: [70] Power Management version 3 Capabilities: [a8] SATA HBA v1.0 Capabilities: [b0] PCI Advanced Features Kernel driver in use: ahci With 6 ports just 8 MSI vectors should be enough, but the adapter enforces the MRSM mode when less than 16 vectors are written to the Multiple Messages Enable PCI register. I instigated MRSM mode by forcing @nvec to 8 in ahci_init_interrupts(). Signed-off-by: Alexander Gordeev Cc: linux-ide@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 9 ++++++++- drivers/ata/ahci.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e45b18ee04c3..f6b3e31f63cd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1164,7 +1164,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) #endif static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, - struct ahci_host_priv *hpriv) + struct ahci_host_priv *hpriv) { int nvec; @@ -1189,6 +1189,13 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, else if (nvec < 0) goto intx; + /* fallback to single MSI mode if the controller enforced MRSM mode */ + if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { + pci_disable_msi(pdev); + printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); + goto single_msi; + } + return nvec; single_msi: diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 51af275b3388..b5eb886da226 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -94,6 +94,7 @@ enum { /* HOST_CTL bits */ HOST_RESET = (1 << 0), /* reset controller; self-clear */ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ + HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ From ccf8f53cac7d9321c9af2b14af41e703f44ac198 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 17 Apr 2014 14:13:50 +0200 Subject: [PATCH 0248/1034] ahci: Use pci_enable_msi_exact() instead of pci_enable_msi_range() The driver calls pci_enable_msi_range() function with the range of [nvec..nvec] which is what pci_enable_msi_exact() function is for. Signed-off-by: Alexander Gordeev Cc: linux-ide@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f6b3e31f63cd..44d40c746982 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1166,7 +1166,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, struct ahci_host_priv *hpriv) { - int nvec; + int rc, nvec; if (hpriv->flags & AHCI_HFLAG_NO_MSI) goto intx; @@ -1183,10 +1183,10 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, if (nvec < n_ports) goto single_msi; - nvec = pci_enable_msi_range(pdev, nvec, nvec); - if (nvec == -ENOSPC) + rc = pci_enable_msi_exact(pdev, nvec); + if (rc == -ENOSPC) goto single_msi; - else if (nvec < 0) + else if (rc < 0) goto intx; /* fallback to single MSI mode if the controller enforced MRSM mode */ From 252455c40316009cc791f00338ee2e367d2d2739 Mon Sep 17 00:00:00 2001 From: Suresh Gupta Date: Fri, 21 Mar 2014 16:38:12 +0530 Subject: [PATCH 0249/1034] usb: gadget: fsl driver pullup fix This fix the fsl usb gadget driver in a way that the usb device will be only "pulled up" on requests only when vbus is powered Signed-off-by: Suresh Gupta Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index dcd0b07ae3a0..a2f26cdb56fe 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1219,6 +1219,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) struct fsl_udc *udc; udc = container_of(gadget, struct fsl_udc, gadget); + + if (!udc->vbus_active) + return -EOPNOTSUPP; + udc->softconnect = (is_on != 0); if (can_pullup(udc)) fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), From 01f8fa4f01d8362358eb90e412bd7ae18a3ec1ad Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:44 +0000 Subject: [PATCH 0250/1034] genirq: Allow forcing cpu affinity of interrupts The current implementation of irq_set_affinity() refuses rightfully to route an interrupt to an offline cpu. But there is a special case, where this is actually desired. Some of the ARM SoCs have per cpu timers which require setting the affinity during cpu startup where the cpu is not yet in the online mask. If we can't do that, then the local timer interrupt for the about to become online cpu is routed to some random online cpu. The developers of the affected machines tried to work around that issue, but that results in a massive mess in that timer code. We have a yet unused argument in the set_affinity callbacks of the irq chips, which I added back then for a similar reason. It was never required so it got not used. But I'm happy that I never removed it. That allows us to implement a sane handling of the above scenario. So the affected SoC drivers can add the required force handling to their interrupt chip, switch the timer code to irq_force_affinity() and things just work. This does not affect any existing user of irq_set_affinity(). Tagged for stable to allow a simple fix of the affected SoC clock event drivers. Reported-and-tested-by: Krzysztof Kozlowski Signed-off-by: Thomas Gleixner Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143315.717251504@linutronix.de Signed-off-by: Thomas Gleixner --- arch/mips/cavium-octeon/octeon-irq.c | 2 +- include/linux/interrupt.h | 35 +++++++++++++++++++++++++++- include/linux/irq.h | 3 ++- kernel/irq/manage.c | 17 +++++--------- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c2bb4f896ce7..3aa5b46b2d40 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data) cpumask_clear(&new_affinity); cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); } - __irq_set_affinity_locked(data, &new_affinity); + irq_set_affinity_locked(data, &new_affinity, false); } static int octeon_irq_ciu_set_affinity(struct irq_data *data, diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c7bfac1c4a7b..8834a7e5b944 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -203,7 +203,40 @@ static inline int check_wakeup_irqs(void) { return 0; } extern cpumask_var_t irq_default_affinity; -extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask); +/* Internal implementation. Use the helpers below */ +extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask, + bool force); + +/** + * irq_set_affinity - Set the irq affinity of a given irq + * @irq: Interrupt to set affinity + * @mask: cpumask + * + * Fails if cpumask does not contain an online CPU + */ +static inline int +irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) +{ + return __irq_set_affinity(irq, cpumask, false); +} + +/** + * irq_force_affinity - Force the irq affinity of a given irq + * @irq: Interrupt to set affinity + * @mask: cpumask + * + * Same as irq_set_affinity, but without checking the mask against + * online cpus. + * + * Solely for low level cpu hotplug code, where we need to make per + * cpu interrupts affine before the cpu becomes online. + */ +static inline int +irq_force_affinity(unsigned int irq, const struct cpumask *cpumask) +{ + return __irq_set_affinity(irq, cpumask, true); +} + extern int irq_can_set_affinity(unsigned int irq); extern int irq_select_affinity(unsigned int irq); diff --git a/include/linux/irq.h b/include/linux/irq.h index d278838908cb..10a0b1ac4ea0 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -394,7 +394,8 @@ extern void remove_percpu_irq(unsigned int irq, struct irqaction *act); extern void irq_cpu_online(void); extern void irq_cpu_offline(void); -extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); +extern int irq_set_affinity_locked(struct irq_data *data, + const struct cpumask *cpumask, bool force); #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) void irq_move_irq(struct irq_data *data); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 2486a4c1a710..d34131ca372b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -180,7 +180,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_chip *chip = irq_data_get_irq_chip(data); int ret; - ret = chip->irq_set_affinity(data, mask, false); + ret = chip->irq_set_affinity(data, mask, force); switch (ret) { case IRQ_SET_MASK_OK: cpumask_copy(data->affinity, mask); @@ -192,7 +192,8 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, return ret; } -int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) +int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask, + bool force) { struct irq_chip *chip = irq_data_get_irq_chip(data); struct irq_desc *desc = irq_data_to_desc(data); @@ -202,7 +203,7 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) return -EINVAL; if (irq_can_move_pcntxt(data)) { - ret = irq_do_set_affinity(data, mask, false); + ret = irq_do_set_affinity(data, mask, force); } else { irqd_set_move_pending(data); irq_copy_pending(desc, mask); @@ -217,13 +218,7 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) return ret; } -/** - * irq_set_affinity - Set the irq affinity of a given irq - * @irq: Interrupt to set affinity - * @mask: cpumask - * - */ -int irq_set_affinity(unsigned int irq, const struct cpumask *mask) +int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; @@ -233,7 +228,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *mask) return -EINVAL; raw_spin_lock_irqsave(&desc->lock, flags); - ret = __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask); + ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force); raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } From ffde1de64012c406dfdda8690918248b472f24e4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:44 +0000 Subject: [PATCH 0251/1034] irqchip: Gic: Support forced affinity setting To support the affinity setting of per cpu timers in the early startup of a not yet online cpu, implement the force logic, which disables the cpu online check. Tagged for stable to allow a simple fix of the affected SoC clock event drivers. Signed-off-by: Thomas Gleixner Tested-by: Krzysztof Kozlowski Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143315.916984416@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-gic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4300b6606f5e..57d165e026f4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -246,10 +246,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); - unsigned int shift = (gic_irq(d) % 4) * 8; - unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); + unsigned int cpu, shift = (gic_irq(d) % 4) * 8; u32 val, mask, bit; + if (!force) + cpu = cpumask_any_and(mask_val, cpu_online_mask); + else + cpu = cpumask_first(mask_val); + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; From 30ccf03b4a6a2102a2219058bdc6d779dc637dd7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:45 +0000 Subject: [PATCH 0252/1034] clocksource: Exynos_mct: Use irq_force_affinity() in cpu bringup The starting cpu is not yet in the online mask so irq_set_affinity() fails which results in per cpu timers for this cpu ending up on some other online cpu, ususally cpu 0. Use irq_force_affinity() which disables the online mask check and makes things work. Signed-off-by: Thomas Gleixner Tested-by: Krzysztof Kozlowski Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143316.106665251@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/clocksource/exynos_mct.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index a6ee6d7cd63f..b2d416368711 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -430,6 +430,7 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->irq); return -EIO; } + irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu)); } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } @@ -450,7 +451,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { struct mct_clock_event_device *mevt; - unsigned int cpu; /* * Grab cpu pointer in each case to avoid spurious @@ -461,12 +461,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_setup(&mevt->evt); break; - case CPU_ONLINE: - cpu = (unsigned long)hcpu; - if (mct_int_type == MCT_INT_SPI) - irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], - cpumask_of(cpu)); - break; case CPU_DYING: mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_stop(&mevt->evt); From 8db6e5104b77de5d0b7002b95069da0992a34be9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 16 Apr 2014 14:36:45 +0000 Subject: [PATCH 0253/1034] clocksource: Exynos_mct: Register clock event after request_irq() After hotplugging CPU1 the first call of interrupt handler for CPU1 oneshot timer was called on CPU0 because it fired before setting IRQ affinity. Affected are SoCs where Multi Core Timer interrupts are shared (SPI), e.g. Exynos 4210. During setup of the MCT timers the clock event device should be registered after setting the affinity for interrupt. This will prevent starting the timer too early. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Thomas Gleixner Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143316.299247848@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/clocksource/exynos_mct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index b2d416368711..acf5a329d538 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -416,8 +416,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->set_mode = exynos4_tick_set_mode; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->rating = 450; - clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), - 0xf, 0x7fffffff); exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); @@ -434,6 +432,8 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), + 0xf, 0x7fffffff); return 0; } From 4991a628a789dc5954e98e79476d9808812292ec Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 08:44:12 -0400 Subject: [PATCH 0254/1034] locks: allow __break_lease to sleep even when break_time is 0 A fl->fl_break_time of 0 has a special meaning to the lease break code that basically means "never break the lease". knfsd uses this to ensure that leases don't disappear out from under it. Unfortunately, the code in __break_lease can end up passing this value to wait_event_interruptible as a timeout, which prevents it from going to sleep at all. This causes __break_lease to spin in a tight loop and causes soft lockups. Fix this by ensuring that we pass a minimum value of 1 as a timeout instead. Cc: Cc: J. Bruce Fields Reported-by: Terry Barnaby Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/locks.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 13fc7a6d380a..b380f5543614 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1391,11 +1391,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) restart: break_time = flock->fl_break_time; - if (break_time != 0) { + if (break_time != 0) break_time -= jiffies; - if (break_time == 0) - break_time++; - } + if (break_time == 0) + break_time++; locks_insert_block(flock, new_fl); spin_unlock(&inode->i_lock); error = wait_event_interruptible_timeout(new_fl->fl_wait, From 3758cf7e14b753838fe754ede3862af10b35fdac Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 08:51:48 -0400 Subject: [PATCH 0255/1034] nfsd: set timeparms.to_maxval in setup_callback_client ...otherwise the logic in the timeout handling doesn't work correctly. Spotted-by: Trond Myklebust Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4callback.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 39c8ef875f91..2c73cae9899d 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -654,9 +654,11 @@ static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args) static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) { + int maxtime = max_cb_time(clp->net); struct rpc_timeout timeparms = { - .to_initval = max_cb_time(clp->net), + .to_initval = maxtime, .to_retries = 0, + .to_maxval = maxtime, }; struct rpc_create_args args = { .net = clp->net, From fc208d026be0c7d60db9118583fc62f6ca97743d Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 9 Apr 2014 11:07:01 -0400 Subject: [PATCH 0256/1034] Revert "nfsd4: fix nfs4err_resource in 4.1 case" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we're still limiting attributes to a page, the result here is that a large getattr result will return NFS4ERR_REP_TOO_BIG/TOO_BIG_TO_CACHE instead of NFS4ERR_RESOURCE. Both error returns are wrong, and the real bug here is the arbitrary limit on getattr results, fixed by as-yet out-of-tree patches. But at a minimum we can make life easier for clients by sticking to one broken behavior in released kernels instead of two.... Trond says: one immediate consequence of this patch will be that NFSv4.1 clients will now report EIO instead of EREMOTEIO if they hit the problem. That may make debugging a little less obvious. Another consequence will be that if we ever do try to add client side handling of NFS4ERR_REP_TOO_BIG, then we now have to deal with the “handle existing buggy server” syndrome. Reported-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2723c1badd01..18881f34737a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3627,14 +3627,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) /* nfsd4_check_resp_size guarantees enough room for error status */ if (!op->status) op->status = nfsd4_check_resp_size(resp, 0); - if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) { - struct nfsd4_slot *slot = resp->cstate.slot; - - if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) - op->status = nfserr_rep_too_big_to_cache; - else - op->status = nfserr_rep_too_big; - } if (so) { so->so_replay.rp_status = op->status; so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1); From df7926fffa9a4c0bceb0189386b4c5edc012fcbb Mon Sep 17 00:00:00 2001 From: Tim Kryger Date: Thu, 17 Apr 2014 11:55:24 -0700 Subject: [PATCH 0257/1034] regulator: core: Return error in get optional stub Drivers that call regulator_get_optional are tolerant to the absence of that regulator. By modifying the value returned from the stub function to match that seen when a regulator isn't present, callers can wrap the regulator logic with an IS_ERR based conditional even if they happen to call regulator_is_supported_voltage. This improves efficiency as well as eliminates the possibility for a very subtle bug. Signed-off-by: Tim Kryger Reviewed-by: Alex Elder Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index e530681bea70..1a4a8c157b31 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -258,14 +258,14 @@ regulator_get_exclusive(struct device *dev, const char *id) static inline struct regulator *__must_check regulator_get_optional(struct device *dev, const char *id) { - return NULL; + return ERR_PTR(-ENODEV); } static inline struct regulator *__must_check devm_regulator_get_optional(struct device *dev, const char *id) { - return NULL; + return ERR_PTR(-ENODEV); } static inline void regulator_put(struct regulator *regulator) From cab27258b1fdaad6380c971917b22d8d54abb7f5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 17 Apr 2014 13:42:54 +0100 Subject: [PATCH 0258/1034] ASoC: wm_adsp: Remove uneeded semicolon Reported-by: kbuild test robot Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bb5f7b4e3ebb..53e3ab5fa0de 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1625,7 +1625,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, break; default: break; - }; + } return 0; } From 694c793fc1ade0946149c5f8d43f71e0728c4e81 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:21:15 -0400 Subject: [PATCH 0259/1034] ext4: use truncate_pagecache() in collapse range We should be using truncate_pagecache() instead of truncate_pagecache_range() in the collapse range because we're truncating page cache from offset to the end of file. truncate_pagecache() also get rid of the private COWed pages from the range because we're going to shift the end of the file. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 64b400356cad..3de9b2d7028c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5437,7 +5437,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) goto out_mutex; } - truncate_pagecache_range(inode, offset, -1); + truncate_pagecache(inode, offset); /* Wait for existing dio to complete */ ext4_inode_block_unlocked_dio(inode); From 1676014ef974ce71a854e7f415e2bb52feb24868 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Sun, 13 Apr 2014 12:45:10 +0200 Subject: [PATCH 0260/1034] spi: atmel: Fix scheduling while atomic bug atmel_spi_lock does a spin_lock_irqsave, so we need to renable the interrupts when we want to schedule. Signed-off-by: Alexander Stein Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8005f9869481..079e6b1b0cdb 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1115,8 +1115,11 @@ static int atmel_spi_one_transfer(struct spi_master *master, atmel_spi_next_xfer_pio(master, xfer); } + /* interrupts are disabled, so free the lock for schedule */ + atmel_spi_unlock(as); ret = wait_for_completion_timeout(&as->xfer_completion, SPI_DMA_TIMEOUT); + atmel_spi_lock(as); if (WARN_ON(ret == 0)) { dev_err(&spi->dev, "spi trasfer timeout, err %d\n", ret); From 1a66c7c3bea52ba0f7596b8940d74fce75281d16 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:41:52 -0400 Subject: [PATCH 0261/1034] ext4: use filemap_write_and_wait_range() correctly in collapse range Currently we're passing -1 as lend argumnet for filemap_write_and_wait_range() which is wrong since lend is signed type so it would cause some confusion and we might not write_and_wait for the entire range we're expecting to write. Fix it by using LLONG_MAX instead. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3de9b2d7028c..f4a676908b0b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5415,7 +5415,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) } /* Write out all dirty pages */ - ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1); + ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); if (ret) return ret; From 2c1d23289bc2f7cfa358bc856b87a992dcb11ad5 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:43:21 -0400 Subject: [PATCH 0262/1034] ext4: fix removing status extents in ext4_collapse_range() Currently in ext4_collapse_range() when calling ext4_es_remove_extent() to remove status extents we're passing (EXT_MAX_BLOCKS - punch_start - 1) in order to remove all extents from start of the collapse range to the end of the file. However this is wrong because we might miss the possible extent covering the last block of the file. Fix it by removing the -1. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Reviewed-by: Namjae Jeon --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f4a676908b0b..c6f624582d37 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5454,7 +5454,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ext4_discard_preallocations(inode); ret = ext4_es_remove_extent(inode, punch_start, - EXT_MAX_BLOCKS - punch_start - 1); + EXT_MAX_BLOCKS - punch_start); if (ret) { up_write(&EXT4_I(inode)->i_data_sem); goto out_stop; From 9337d5d31ab798f0c74150506371551a9195251a Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:48:25 -0400 Subject: [PATCH 0263/1034] ext4: no need to truncate pagecache twice in collapse range We're already calling truncate_pagecache() before we attempt to do any actual job so there is not need to truncate pagecache once more using truncate_setsize() after we're finished. Remove truncate_setsize() and replace it just with i_size_write() note that we're holding appropriate locks. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c6f624582d37..3ee60e2e2ac7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5474,7 +5474,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) } new_size = i_size_read(inode) - len; - truncate_setsize(inode, new_size); + i_size_write(inode, new_size); EXT4_I(inode)->i_disksize = new_size; ext4_discard_preallocations(inode); From ef24f6c234de9a03aed9368163dbaad9a4f6391f Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:50:23 -0400 Subject: [PATCH 0264/1034] ext4: discard preallocations after removing space Currently in ext4_collapse_range() and ext4_punch_hole() we're discarding preallocation twice. Once before we attempt to do any changes and second time after we're done with the changes. While the second call to ext4_discard_preallocations() in ext4_punch_hole() case is not needed, we need to discard preallocation right after ext4_ext_remove_space() in collapse range case because in the case we had to restart a transaction in the middle of removing space we might have new preallocations created. Remove unneeded ext4_discard_preallocations() ext4_punch_hole() and move it to the better place in ext4_collapse_range() Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- fs/ext4/inode.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3ee60e2e2ac7..eb7be8f08e10 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5465,6 +5465,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) up_write(&EXT4_I(inode)->i_data_sem); goto out_stop; } + ext4_discard_preallocations(inode); ret = ext4_ext_shift_extents(inode, handle, punch_stop, punch_stop - punch_start); @@ -5477,7 +5478,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) i_size_write(inode, new_size); EXT4_I(inode)->i_disksize = new_size; - ext4_discard_preallocations(inode); up_write(&EXT4_I(inode)->i_data_sem); if (IS_SYNC(inode)) ext4_handle_sync(handle); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b74cfd2a42ec..d7b7462a0e13 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3621,7 +3621,6 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) ret = ext4_free_hole_blocks(handle, inode, first_block, stop_block); - ext4_discard_preallocations(inode); up_write(&EXT4_I(inode)->i_data_sem); if (IS_SYNC(inode)) ext4_handle_sync(handle); From 3477501274b79a904a4195b675bb74caa57d2e14 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 17 Apr 2014 20:12:56 +0800 Subject: [PATCH 0265/1034] ASoC: dapm: Allow update_bits use 32 bits reg This patch change reg's type from unsigned short to int. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c8a780d0d057..f4ba7b40a6ab 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -426,7 +426,7 @@ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) } static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, - unsigned short reg, unsigned int mask, unsigned int value) + int reg, unsigned int mask, unsigned int value) { bool change; unsigned int old, new; From 6dd834effc12ba71092d9d1e4944530234b58ab1 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:55:24 -0400 Subject: [PATCH 0266/1034] ext4: fix extent merging in ext4_ext_shift_path_extents() There is a bug in ext4_ext_shift_path_extents() where if we actually manage to merge a extent we would skip shifting the next extent. This will result in in one extent in the extent tree not being properly shifted. This is causing failure in various xfstests tests using fsx or fsstress with collapse range support. It will also cause file system corruption which looks something like: e2fsck 1.42.9 (4-Feb-2014) Pass 1: Checking inodes, blocks, and sizes Inode 20 has out of order extents (invalid logical block 3, physical block 492938, len 2) Clear? yes ... when running e2fsck. It's also very easily reproducible just by running fsx without any parameters. I can usually hit the problem within a minute. Fix it by increasing ex_start only if we're not merging the extent. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Reviewed-by: Namjae Jeon --- fs/ext4/extents.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index eb7be8f08e10..d0860f2d36d0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5245,13 +5245,14 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, while (ex_start <= ex_last) { le32_add_cpu(&ex_start->ee_block, -shift); - if (ex_start > - EXT_FIRST_EXTENT(path[depth].p_hdr)) { - if (ext4_ext_try_to_merge_right(inode, - path, ex_start - 1)) - ex_last--; - } - ex_start++; + /* Try to merge to the left. */ + if ((ex_start > + EXT_FIRST_EXTENT(path[depth].p_hdr)) && + ext4_ext_try_to_merge_right(inode, + path, ex_start - 1)) + ex_last--; + else + ex_start++; } err = ext4_ext_dirty(handle, inode, path + depth); if (err) From 1025c05f727be33e065bb502a223637681c7991d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 17 Apr 2014 16:35:43 +0800 Subject: [PATCH 0267/1034] ASoC: cs42l51: Fix mask for REVID The REVID mask was changed by commit a1253ef6d3fa "ASoC: cs42l51: split i2c from codec driver". Fix it. Signed-off-by: Axel Lin Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51.c | 3 ++- sound/soc/codecs/cs42l51.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 46abd3e02f14..6aa69e5aaa3f 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -548,7 +548,8 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap) ret = -ENODEV; goto error; } - dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", val & 0xFF); + dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", + val & CS42L51_CHIP_REV_MASK); ret = snd_soc_register_codec(dev, &soc_codec_device_cs42l51, &cs42l51_dai, 1); diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index 641ef18435b3..8c55bf384bc6 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h @@ -26,6 +26,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap); #define CS42L51_CHIP_ID 0x1B #define CS42L51_CHIP_REV_A 0x00 #define CS42L51_CHIP_REV_B 0x01 +#define CS42L51_CHIP_REV_MASK 0x07 #define CS42L51_CHIP_REV_ID 0x01 #define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b)) From 6c5e73d3a26b73bfcac0b4a932cb918177d067f2 Mon Sep 17 00:00:00 2001 From: jon ernst Date: Fri, 18 Apr 2014 11:50:35 -0400 Subject: [PATCH 0268/1034] ext4: enforce we are operating on a regular file in ext4_zero_range() Signed-off-by: Jon Ernst Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index d0860f2d36d0..2f49b12a4c40 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4741,6 +4741,9 @@ static long ext4_zero_range(struct file *file, loff_t offset, trace_ext4_zero_range(inode, offset, len, mode); + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + /* * Write out all dirty pages to avoid race conditions * Then release them. From 86f1ca3889142d5959362c5694db3f3dc26f377a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 18 Apr 2014 11:52:11 -0400 Subject: [PATCH 0269/1034] ext4: use EINVAL if not a regular file in ext4_collapse_range() Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2f49b12a4c40..9b9251adb400 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5404,7 +5404,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) return -EINVAL; if (!S_ISREG(inode->i_mode)) - return -EOPNOTSUPP; + return -EINVAL; trace_ext4_collapse_range(inode, offset, len); From b7580cde704920da69e50d133cea16eca77ff3bd Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Tue, 15 Apr 2014 22:39:01 +0200 Subject: [PATCH 0270/1034] ASoC: core: use PTR_ERR instead of PTR_RET PTR_RET is deprecated. PTR_ERR_OR_ZERO should be used instead. However, we already know that IS_ERR is true, and thus PTR_ERR_OR_ZERO would never yield zero, so we can use PTR_ERR here. Signed-off-by: Christoph Jaeger Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 78f0c51c6c83..7f8efea5c5b1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2075,28 +2075,28 @@ static int snd_soc_ac97_parse_pinctl(struct device *dev, p = devm_pinctrl_get(dev); if (IS_ERR(p)) { dev_err(dev, "Failed to get pinctrl\n"); - return PTR_RET(p); + return PTR_ERR(p); } cfg->pctl = p; state = pinctrl_lookup_state(p, "ac97-reset"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-reset\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_reset = state; state = pinctrl_lookup_state(p, "ac97-warm-reset"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_warm_reset = state; state = pinctrl_lookup_state(p, "ac97-running"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-running\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_run = state; From 8931bf6208776292b1b888dd8534229f63e2eaa2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:11 +0300 Subject: [PATCH 0271/1034] ASoC: Add resource managed snd_soc_register_platform() Simplify error handling and remove repetitive (and rarely executed) code for unregistration by providing a devm_snd_soc_register_platform() platform. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- include/sound/soc.h | 2 ++ sound/soc/soc-devres.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..34c34d6e095c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -377,6 +377,8 @@ int snd_soc_resume(struct device *dev); int snd_soc_poweroff(struct device *dev); int snd_soc_register_platform(struct device *dev, const struct snd_soc_platform_driver *platform_drv); +int devm_snd_soc_register_platform(struct device *dev, + const struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv); diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 7ac745df1412..e94aa0277250 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -52,6 +52,40 @@ int devm_snd_soc_register_component(struct device *dev, } EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); +static void devm_platform_release(struct device *dev, void *res) +{ + snd_soc_unregister_platform(*(struct device **)res); +} + +/** + * devm_snd_soc_register_platform - resource managed platform registration + * @dev: Device used to manage platform + * @platform: platform to register + * + * Register a platform driver with automatic unregistration when the device is + * unregistered. + */ +int devm_snd_soc_register_platform(struct device *dev, + const struct snd_soc_platform_driver *platform_drv) +{ + struct device **ptr; + int ret; + + ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = snd_soc_register_platform(dev, platform_drv); + if (ret == 0) { + *ptr = dev; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} + static void devm_card_release(struct device *dev, void *res) { snd_soc_unregister_card(*(struct snd_soc_card **)res); From f6563b31fb4878fddc846d2012bcee9c5f260d11 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:13 +0300 Subject: [PATCH 0272/1034] ASoC: omap-mcpdm: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2f5b1536477e..e984b0485e92 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -265,9 +265,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, } mutex_unlock(&mcpdm->mutex); - snd_soc_dai_set_dma_data(dai, substream, - &mcpdm->dma_data[substream->stream]); - return 0; } @@ -406,6 +403,11 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = MCPDM_UP_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, + &mcpdm->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcpdm->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return ret; } From 335b06515eda252b36aa9063596f740a903c1e35 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:14 +0300 Subject: [PATCH 0273/1034] ASoC: omap-mcpdm: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index e984b0485e92..d8ebb52645a9 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -42,6 +42,7 @@ #include #include "omap-mcpdm.h" +#include "omap-pcm.h" struct mcpdm_link_config { u32 link_mask; /* channel mask for the direction */ @@ -462,6 +463,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) { struct omap_mcpdm *mcpdm; struct resource *res; + int ret; mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); if (!mcpdm) @@ -492,9 +494,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; - return devm_snd_soc_register_component(&pdev->dev, + ret = devm_snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, &omap_mcpdm_dai, 1); + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static const struct of_device_id omap_mcpdm_of_match[] = { From 3fe856b3127744ce30d4369ba760459b6ac9f820 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:15 +0300 Subject: [PATCH 0274/1034] ASoC: omap-mcbsp: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6c19bba23570..4525190d5599 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -149,9 +149,6 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); } - snd_soc_dai_set_dma_data(cpu_dai, substream, - &mcbsp->dma_data[substream->stream]); - return err; } @@ -559,6 +556,10 @@ static int omap_mcbsp_probe(struct snd_soc_dai *dai) pm_runtime_enable(mcbsp->dev); + snd_soc_dai_init_dma_data(dai, + &mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return 0; } From 64241425b8eaf46c971b6ba400c21f71979e6782 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:16 +0300 Subject: [PATCH 0275/1034] ASoC: omap-mcbsp: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 4525190d5599..af2764adf252 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -38,6 +38,7 @@ #include #include "mcbsp.h" #include "omap-mcbsp.h" +#include "omap-pcm.h" #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) @@ -800,11 +801,15 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mcbsp); ret = omap_mcbsp_init(pdev); - if (!ret) - return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, - &omap_mcbsp_dai, 1); + if (ret) + return ret; - return ret; + ret = snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, + &omap_mcbsp_dai, 1); + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static int asoc_mcbsp_remove(struct platform_device *pdev) From fe7b5868809a89a7316eef064f0bb7796aa8c225 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:12 +0300 Subject: [PATCH 0276/1034] ASoC: omap-pcm: Support for binding the platform driver to dai devices With the new calls it is going to be possible to bind the platform driver to a dai device which makes it easier for us in a long run to handle DT boots, and opens the possibility to move machine driver to generic simple card. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 6 ++++++ sound/soc/omap/omap-pcm.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 sound/soc/omap/omap-pcm.h diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07b8b7bc9d20..c3711b582d5f 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -232,6 +232,12 @@ static struct snd_soc_platform_driver omap_soc_platform = { .pcm_free = omap_pcm_free_dma_buffers, }; +int omap_pcm_platform_register(struct device *dev) +{ + return devm_snd_soc_register_platform(dev, &omap_soc_platform); +} +EXPORT_SYMBOL_GPL(omap_pcm_platform_register); + static int omap_pcm_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h new file mode 100644 index 000000000000..c1d2f31d71e9 --- /dev/null +++ b/sound/soc/omap/omap-pcm.h @@ -0,0 +1,30 @@ +/* + * omap-pcm.h - OMAP PCM driver + * + * Copyright (C) 2014 Texas Instruments, Inc. + * + * Author: Peter Ujfalusi + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __OMAP_PCM_H__ +#define __OMAP_PCM_H__ + +#if IS_ENABLED(CONFIG_SND_OMAP_SOC) +int omap_pcm_platform_register(struct device *dev); +#else +static inline int omap_pcm_platform_register(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_SND_OMAP_SOC */ + +#endif /* __OMAP_PCM_H__ */ From 3802a259272e48870b8d7e02c4fc28f938a699cb Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:17 +0300 Subject: [PATCH 0277/1034] ASoC: omap-dmic: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 1bd531d718f9..7fb7703264fa 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -113,7 +113,6 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_unlock(&dmic->mutex); - snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); return ret; } @@ -417,6 +416,9 @@ static int omap_dmic_probe(struct snd_soc_dai *dai) /* Configure DMIC threshold value */ dmic->threshold = OMAP_DMIC_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, NULL, &dmic->dma_data); + return 0; } From 18d7cfea28fe7e06047abef40a18db2643a427be Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:18 +0300 Subject: [PATCH 0278/1034] ASoC: omap-dmic: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 7fb7703264fa..53da041896c4 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -42,6 +42,7 @@ #include #include "omap-dmic.h" +#include "omap-pcm.h" struct omap_dmic { struct device *dev; @@ -494,6 +495,10 @@ static int asoc_dmic_probe(struct platform_device *pdev) if (ret) goto err_put_clk; + ret = omap_pcm_platform_register(&pdev->dev); + if (ret) + goto err_put_clk; + return 0; err_put_clk: From 9769824cf9ca4bb877146dbec2695bdbf577c499 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:19 +0300 Subject: [PATCH 0279/1034] ASoC: omap-hdmi: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-hdmi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index ced3b88b44d4..32614b49653c 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -36,6 +36,7 @@ #include